Server-sent Events(SSE)是一种用于向客户端发送服务器端事件的技术,它允许服务器主动向客户端推送数据,而无需客户端发起请求。SSE 可以用于实时通信、实时更新和实时监控等场景,它比 WebSocket 更加轻量级,适用于在浏览器中实现轻量级的实时通信。
在 Node.js 应用程序中使用 SSE,我们需要使用第三方库,比如 sse-express 或 server-sent-events。这里我们以 sse-express 为例进行讲解。
1. 安装 sse-express
我们可以使用 npm 安装 sse-express:
npm install sse-express
2. 创建 SSE 服务
我们可以使用 sse-express 创建 SSE 服务:
-- -------------------- ---- ------- ----- ---------- - ----------------------- ----- ------- - ------------------- ----- --- - ---------- --------------- ------------- ----- ---- -- - -------------- -- - -------------- - - --- ------ - -------- -- ------ --- ---------------- -- -- - ------------------- ------- -- ------------------------ ---展开代码
在上面的代码中,我们创建了一个 SSE 服务,它会每秒钟向客户端推送一条消息,消息内容为当前时间。
3. 在客户端接收 SSE 数据
在客户端,我们可以使用 EventSource 对象接收 SSE 数据:
const source = new EventSource('/sse'); source.onmessage = event => { console.log(event.data); };
在上面的代码中,我们创建了一个 EventSource 对象,它会向 /sse
发起连接请求,并监听 onmessage
事件,当 SSE 服务向客户端推送消息时,onmessage
事件会被触发,我们可以在事件处理函数中处理消息。
4. SSE 的最佳实践
4.1 使用 gzip 压缩 SSE 数据
SSE 数据的传输是基于 HTTP 的,因此我们可以使用 gzip 压缩 SSE 数据,减少网络传输的数据量,提高传输效率。我们可以使用 compression 中间件进行 gzip 压缩:
-- -------------------- ---- ------- ----- ----------- - ----------------------- ----- ---------- - ----------------------- ----- ------- - ------------------- ----- --- - ---------- ----------------------- --------------- ------------- ----- ---- -- - -------------- -- - -------------- - - --- ------ - -------- -- ------ --- ---------------- -- -- - ------------------- ------- -- ------------------------ ---展开代码
在上面的代码中,我们使用 app.use(compression())
启用 gzip 压缩。
4.2 使用 Last-Event-ID 处理断开连接和重连
SSE 数据传输是基于 HTTP 长连接的,因此客户端可能会因为网络原因或其他原因断开连接。在这种情况下,客户端需要重新连接 SSE 服务,而 SSE 服务需要保证客户端能够接收到之前未接收到的消息。为了实现这一点,我们可以使用 Last-Event-ID 头部来处理断开连接和重连:
-- -------------------- ---- ------- ----- ---------- - ----------------------- ----- ------- - ------------------- ----- --- - ---------- --------------- ------------- ----- ---- -- - ----- ----------- - ---------------------------- -- -- --- ----- - ------------ -------------- -- - -------- ------------ --------------- ----- -------------- -- ------ --- ---------------- -- -- - ------------------- ------- -- ------------------------ ---展开代码
在上面的代码中,我们使用 req.headers['last-event-id']
获取客户端最后接收到的消息 ID,然后使用 res.sse(
id: ${count}\ndata: ${new Date()}\n\n)
发送消息,每个消息都包含一个 ID,客户端可以使用这个 ID 来判断是否有消息丢失。
4.3 使用 Redis 实现多进程 SSE
SSE 服务可能需要处理大量的客户端连接,这时候单进程的 SSE 服务可能无法满足需求。为了解决这个问题,我们可以使用 Redis 来实现多进程 SSE:
-- -------------------- ---- ------- ----- ---------- - ----------------------- ----- ------- - ------------------- ----- ----- - ----------------- ----- ------- - ------------------- ----- ------- - ---------------------------- ----- --- - ---------- -- ------------------ - --- ---- - - -- - - -------- ---- - --------------- - - ---- - ----- ----------- - --------------------- ----- ---------- - --------------------- --------------- ------------- ----- ---- -- - ----- ----------- - ---------------------------- -- -- --- ----- - ------------ ---------------------------- ------------------------ --------- -------- -- - ----------------- --- --------------- -- -- - ------------------------------ --- -------------- -- - -------- -------------------------- ---- --------------- ----- -------------- -- ------ --- ---------------- -- -- - ------------------- -------------- ------- -- ------------------------ --- -展开代码
在上面的代码中,我们使用 cluster
模块创建多个进程,每个进程都会创建一个 SSE 服务,每个 SSE 服务都会使用 Redis 订阅 sse
频道,当 SSE 服务接收到消息时,会将消息发送给客户端。客户端断开连接时,SSE 服务会取消订阅 sse
频道。
总结
在 Node.js 应用程序中使用 SSE,我们可以使用 sse-express 库来创建 SSE 服务,使用 EventSource 对象来接收 SSE 数据。在实际应用中,我们需要注意 SSE 的最佳实践,比如使用 gzip 压缩 SSE 数据、使用 Last-Event-ID 处理断开连接和重连、使用 Redis 实现多进程 SSE 等。通过合理的使用 SSE 技术,我们可以实现高效的实时通信、实时更新和实时监控等功能。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6510d11595b1f8cacd93678d