在跟着 IBM 的课程学习全栈开发的时候,期间想到了我于两年前写的一个小项目,当时学习了 Python 的 Flask 框架,就异想天开地编写了一个基于频道的聊天室。当时并不知道实时通信的原理,只是简单地用 Flask 和 SQLite—— 连 Socket.io 都没用上 —— 实现了一个简单的类 Slack 聊天室。

现在见识到了更多的技术,年轻莽撞的我自然是想要重写这个项目。不过具体能不能完成,就是另外一回事了。

阅读本文需知道:

  • 我使用 Jetbrains WebStorm 作为 IDE,新建项目也是使用了 WebStorm 提供的模板
  • 写这个文章时我安装的 Node.JS 版本是 v20.11.0、npm 版本是 10.2.4

项目结构

首先,我们需要新建两个文件夹(废话):一个是用于存放前端代码的 client 文件夹,另一个是用于存放后端代码的 server 文件夹。

在 WebStorm 中,先在 client 文件夹中新建一个 React 项目,然后在 server 文件夹中新建一个 Express 项目。

总体的项目结构差不多是这样的:

plaintext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
总项目(其实不放在一起也OK)/
├─ client/
│ ├─ node_modules/
│ ├─ public/
│ ├─ src/
│ │ ├─ App.js
│ │ ├─ index.js
│ ├─ package.json
├─ server/
│ ├─ bin/
│ │ ├─ www
│ ├─ node_modules/
│ ├─ public/
│ ├─ routes/
│ ├─ views/
│ ├─ app.js
│ ├─ package.json
  • client 文件夹中,最重要的便是 src 文件夹,其中的 App.jsindex.js 是 React 项目的入口文件
  • server 文件夹中,最重要的便是 app.js 文件。不过由于 bin/www 文件是服务器的启动关键,所以需要修改它而不是 app.js 文件

后端

我们率先开始装包:

bash
1
npm install socket.io cors nodemon

不装 Express 包自然是因为 WebStorm 已经帮我们装好了,哈哈。

Socket.io 包是我们这次项目的核心。它能够轻松地实现实时通信,也就是多人聊天的基础。Cors 包用于解决跨域问题,比方说我们的前端项目是运行在 localhost:3000,而后端项目是运行在 localhost:4000,这样就会出现跨域问题。而 Nodemon 包是用于自动重启服务器的,这样我们就不用每次修改代码后都手动重启服务器了,懒人福音。

我们直接来看 bin/www 文件。它的一行代码便告诉了我们它的作用:

javascript
1
2
3
4
5
/**
* Create HTTP server.
*/

const server = http.createServer(app);

bin/www 创建了一个 HTTP 服务器,而 app 则是我们的 Express 应用。

在导入依赖的地方,我们先导入 Socket.io 和 Cors 包:

javascript
1
2
const cors = require('cors');
const { Server } = require("socket.io");

要想使用 Cors 包,我们就需要激活它:

javascript
1
app.use(cors());

在 HTTP 服务器被创建之后,我们就需要创建 Socket.io 服务器了:

javascript
1
2
3
4
5
const socketIO = new Server(server, {
cors: {
origin: "http://localhost:3000"
}
});

此处的 cors 选项指定了 React 项目的默认端口,为我们之后的前后端通信提供了便利。

接下来,我们需要监听 Socket.io 服务器的连接事件:

javascript
1
2
3
4
5
6
7
socketIO.on("connection", (socket) => {
console.log(`A user connected: ${socket.id}`);

socket.on("disconnect", () => {
console.log(`A user disconnected: ${socket.id}`);
});
});

这个连接事件会在客户端连接到服务器时触发,打印出客户端的 ID。

最后我们要用上最先装的 Nodemon 包。进入 package.json 文件,找到 scripts 选项,将 start 选项改为:

json
1
2
3
{
"start": "nodemon ./bin/www"
}

至此,我们的 server 目录就可以先不管了。

前端

和后端一样,先来装包:

bash
1
npm install socket.io-client

为啥不装 React 包呢?额…… 不皮了。

Socket.io-client 包是用于在前端连接到 Socket.io 服务器的。

其实前端的代码很简单,我们只需要在 App.js 中写入以下代码:

javascript
1
2
import socketIO from "socket.io-client";
const socket = socketIO.connect("http://localhost:4000");

好了,大功告成,就这么简单。

后话

最后只需要在两个项目中分别运行 npm start,然后打开浏览器窗口,访问 localhost:3000 就可以看到服务端的终端输出了。

为什么我要水这么一篇文章呢?因为我觉得这个项目的基础部分还是挺有意思的,而且我也想把我学到的东西记录下来,以便日后查阅。

好吧其实根本就是今天早上睡过头、压根没时间花在代码上,所以一整天就干了这么点实质性的东西。

水文章还是挺好玩的,以后有机会再水一篇。