引言
在现代 Web 开发中,前端的实时通信需求越来越多,而 WebSocket 提供了一种不同于 Ajax 轮询和长轮询的实时通信方式。但是,实际开发中 WebSocket 的使用不太方便,特别是在协议、适配等方面需要耗费很多精力。这时候,socket.io 库的出现就解决了这些问题,socket.io 基于 WebSocket 实现了简单、快捷、可靠的实时通信。
虽然 socket.io 可以单独使用,但结合 Express 框架使用,可以让我们在前后端分离的场景下更好地进行实时通信。本篇文章将旨在详细介绍 Socket.io 如何与 Express 结合使用,涉及的知识点包括:socket.io 的基本用法、socket.io 与 Express 的结合使用、socket.io 的事件机制等。
Socket.io 简介
Socket.io 是一个面向实时 Web 应用的 JavaScript 库,可以让客户端和服务端之间建立实时的双向通信。socket.io 基于 WebSocket、轮询、长轮询等技术,可以自动选择最优的通信方式,实现了通信效率和兼容性的平衡。
socket.io 的优点如下:
- 支持跨平台,客户端可用于浏览器、Node.js 等平台。
- 简单易用,客户端和服务端均提供了简洁的 API。
- 支持广播(Broadcast)机制,可以让服务端向所有客户端发送消息。
- 可以定制事件,可以自定义事件名称和数据内容。
- 集成了许多插件,如 Redis,可以进行多节点通信。
Socket.io 的基本用法
在介绍 Socket.io 如何与 Express 结合使用之前,我们先来看一下 Socket.io 的基本用法。
创建 Socket 服务器
首先,我们需要用 Node.js 创建一个 Socket 服务器,代码如下:
-- -------------------- ---- ------- ----- --- - ------------------------------- ----- -- - -------------------------- ------------------- ------ -- - -------------- ---- ------------ ----------------------- -- -- - ----------------- --------------- --- --- ---------------- -- -- - ---------------------- -- --------- ---展开代码
代码解析:
- 首先,我们创建了一个 HTTP 服务器
app
。 - 接着,我们将
app
作为参数传入socket.io
函数,创建了一个 Socket 服务器io
。 - 然后,我们通过
io.on('connection', ...)
监听客户端的连接事件,并在回调函数中输出连接成功的信息。 - 最后,我们启动了服务器并监听 3000 端口。
创建 Socket 客户端
客户端的实现也很简单,先来看一下 HTML 代码:
-- -------------------- ---- ------- --------- ----- ------ ------ ---------------- -------------- ------- ------- --------------------------------------- -------- ----- ------ - ----- -------------------- -- -- - ------------------------- --- ----------------------- -- -- - ---------------------------- --- --------- ------ ------------- ----------- ------- -------展开代码
客户端代码解析:
- 首先,我们通过
<script>
标签引入了socket.io.js
脚本。 - 然后,我们通过
const socket = io()
创建了一个 Socket 实例。 - 接着,我们监听了
connect
和disconnect
事件,分别输出连接成功和断开连接的信息。
运行 Socket 服务器和客户端
将上面的代码保存为 server.js
和 index.html
,然后在命令行中运行以下命令:
node server.js
此时,服务器已经启动,然后在浏览器中打开 index.html
文件,打开开发者工具,我们可以看到控制台输出了 connected
,说明客户端已经成功连接了 Socket 服务器。
回到命令行界面,我们可以看到输出了 a user connected
,说明服务器已经成功接受了客户端的连接。
客户端向服务器发送消息
我们可以在客户端中使用 socket.emit
方法向服务器发送消息,代码如下:
socket.emit('chat message', 'Hello, Socket!');
服务器在接收到消息时,会触发相应的事件,在服务器代码中,我们可以这样处理 chat message
事件:
-- -------------------- ---- ------- ------------------- ------ -- - -------------- ---- ------------ --------------- --------- --- -- - --------------------- --------- --- ----------------------- -- -- - ----------------- --------------- --- ---展开代码
上面的代码中,我们监听了 chat message
事件,并在接收到消息时输出了消息的内容。在客户端中可以使用以下代码发送消息:
const sendMessage = () => { const input = document.querySelector('#input'); const message = input.value; socket.emit('chat message', message); input.value = ''; };
服务器向客户端发送消息
服务器向客户端发送消息可以使用 socket.emit
方法,但是这样只能将消息发送给特定的客户端,在广播消息时就不太方便。在 Socket.io 中,我们可以使用 io.emit
方法向所有客户端发送消息:
io.emit('broadcast message', 'Hello, Socket!');
上面的代码在服务器端调用,可以将消息发送给所有已连接的客户端。
广播消息
在实时通信中,广播消息非常常见。广播消息的发送方式有两种:使用 io.emit
发送给所有客户端,或者使用 socket.broadcast.emit
发送给除自己之外的其它客户端。
io.emit('broadcast message', 'Hello, Socket!');
socket.broadcast.emit('broadcast message', 'Hello, Socket!');
上面的代码分别是向所有客户端和除了自己之外的其它客户端发送广播消息。
Socket.io 与 Express 的结合使用
上面我们已经介绍了 Socket.io 的基本用法,接下来介绍 Socket.io 如何与 Express 结合使用,实现更加灵活的实时通信。
安装依赖
在开始之前,我们需要先安装 express 和 socket.io 这两个库:
npm install express socket.io --save
创建 Express 应用
接下来,我们需要创建一个 Express 应用,代码如下:
const express = require('express'); const app = express(); const server = require('http').createServer(app); const io = require('socket.io')(server);
这里需要注意,我们创建了一个 server
对象,将 Express 应用作为参数传入,然后再使用 server
对象来创建 Socket 服务器。
监听连接事件
然后,我们在服务器端监听连接事件,代码如下:
io.on('connection', socket => { console.log(`Socket ${socket.id} connected`); });
上面的代码中,我们监听了 connection
事件,当有客户端连接时会触发此事件,我们在回调函数中输出了连接成功的信息。
发送消息
Socket.io 的传统方式是使用 socket.emit
发送消息,但在 Express 中,我们可以使用 io.emit
来发送广播消息,或者使用 socket.broadcast.emit
发送给除自己之外的客户端。下面的代码实现了向所有客户端发送广播消息:
app.post('/messages', (req, res, next) => { const { message } = req.body; io.emit('new message', message); res.json({ status: 'OK' }); });
在 Express 中,我们通过 app.post
来处理 POST 请求,并通过 req.body
获取请求参数。
监听客户端事件
在 Express 中,我们通过 socket.on
来监听客户端的事件,下面的代码实现了监听客户端发来的消息事件:
-- -------------------- ---- ------- ------------------- ------ -- - ------------------- ------------ ------------ -------------- --------- ------- -- - ---------------- -------- ------------- --- ----------------------- -- -- - ------------------- ------------ --------------- --- ---展开代码
在回调函数中,我们对客户端发来的消息事件进行了处理。当事件被触发时,我们打印出消息的内容。
事件机制
Socket.io 的事件机制让我们可以自定义事件名称和数据内容,并可以在服务器和客户端之间传递消息。
在 Socket.io 中,我们使用 socket.emit
发送事件,同时也可以使用 io.emit
广播事件。
自定义事件名称
默认情况下,Socket.io 为我们提供了几个预定义事件,如 connect
、disconnect
、error
等等,我们也可以自定义事件名称,如下所示:
// 客户端代码 socket.emit('say hello', 'world'); // 服务器端代码 socket.on('say hello', message => { console.log(message); // 输出 'world' });
通过自定义事件名称,我们可以让服务器和客户端之间进行更灵活的通信。
发送数据
在 Socket.io 中,我们可以通过事件的回调函数传递数据。在客户端发送事件时,通过第二个参数向服务器发送数据,如下所示:
socket.emit('chat message', 'Hello, Socket!');
在服务器端接收事件时,可以通过回调函数的参数获取到数据,如下所示:
-- -------------------- ---- ------- ------------------- ------ -- - -------------- ---- ------------ --------------- --------- --- -- - --------------------- --------- --- ----------------------- -- -- - ----------------- --------------- --- ---展开代码
广播事件
在 Socket.io 中,可以使用 io.emit
广播事件,将消息发送给所有客户端。此外,还可以使用 socket.broadcast.emit
发送给除自己之外的其它客户端。如下所示:
// 广播事件 io.emit('broadcast message', 'Hello, Socket!'); // 发送给所有客户端,包括自己 // 除自己之外的其它客户端 socket.broadcast.emit('broadcast message', 'Hello, Socket!');
总结
Socket.io 是一个非常强大和灵活的实时通信库,可以方便地实现前后端的双向通信。在 Express 中,我们可以通过简单的代码来实现 Socket.io 的使用,并可以自定义事件、传递数据和广播消息。Socket.io 的轻量级和易用性是它成为前后端实时通信的佼佼者的原因之一,相信在未来的 Web 开发中,Socket.io 会越来越受到广泛的应用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64811f4048841e989408ac50