使用 Server-sent Events(SSE) 实现长连接推送,解决 WebSocket 不支持问题

在 Web 前端开发中,经常会需要实现实时推送数据的功能,比如在线聊天室、股票行情、实时数据监控等等。为了实现这些功能,常见的做法是使用 WebSocket 进行双向通信。但是有些环境不支持 WebSocket(比如一些编程语言的低版本浏览器),这时就需要考虑其他的方法。本文将介绍一种替代 WebSocket 实现长连接推送的方法 —— Server-sent Events(SSE)。

什么是 Server-sent Events?

Server-sent Events 是一种基于 HTTP 协议的服务器端推送技术,也叫做 EventSource。它的主要作用是允许服务器单向推送数据给客户端,不需要客户端发起请求,服务器可以自动地向客户端发送实时数据。

与 WebSocket 不同,Server-sent Events 使用的是 HTTP 协议,因此它比 WebSocket 更轻量级,更易于部署、维护和扩展。同时,它也比 Ajax 请求更稳定,因为 SSE 与 Web 页面的交互是单向的,所以 SSE 在传输过程中不会占用服务器的带宽和资源。

如何使用 Server-sent Events?

使用 Server-sent Events 的过程非常简单,只需要在客户端使用 JavaScript 创建一个 EventSource 对象,然后指定一个 URL,表示向哪个服务器请求数据。在服务器端,需要监听这个请求,当有数据需要推送给客户端时,就像一个普通的 HTTP 响应一样,发送一段特殊格式的数据给客户端即可。

创建 EventSource 对象

首先,我们需要在客户端使用 JavaScript 创建一个 EventSource 对象,如下所示:

const source = new EventSource(url);

其中,url 是一个字符串类型的参数,表示服务器请求的地址。

监听服务器推送数据

EventSource 对象会自动向服务器创建一个持久的 HTTP 连接,等待服务器推送数据。当服务器推送数据时,我们需要在客户端监听这些数据,如下所示:

source.onmessage = function(event) {
  console.log('Received Event:', event.data);
};

onmessage 是一个 EventSource 对象的属性,用于监听服务器推送的数据。当服务器推送数据时,EventSource 对象会调用 onmessage 函数,并将数据作为参数传递给该函数。

发送服务器推送数据

如果需要向客户端发送实时数据,只需要在服务器端像发送 HTTP 响应一样,发送一段特殊格式的数据即可。这段数据需要符合以下格式:

其中,event 和 data 分别表示事件名称和数据。注意,每一行数据都必须以 \n 结束。

下面是一个简单的 Node.js 服务器示例代码:

const http = require('http');

http.createServer((req, res) => {
  // 设置响应头
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  // 发送实时数据
  setInterval(() => {
    res.write('event: test\n');
    res.write(`data: ${new Date().toLocaleString()}\n\n`);
  }, 1000);
}).listen(8888);

在上面的示例代码中,我们使用 createServer 函数创建一个 Node.js 服务器,并监听 8888 端口。在处理客户端请求时,我们需要设置响应头,如下所示:

其中,Content-Type 指示响应的数据是 text/event-stream 类型,Cache-Control 指示不缓存该响应,Connection 指示一个持久的 HTTP 连接。

在 setInterval 中,我们不断地发送实时数据。在发送时,我们需要按照 Server-sent Events 的格式发送数据,即先发送 event 再发送 data。

总结

通过本文的介绍,我们了解了什么是 Server-sent Events,并学习了如何使用 Server-sent Events 实现长连接推送。相比 WebSocket,Server-sent Events 更为轻量级,更易于部署、维护和扩展。在一些环境不支持 WebSocket 的情况下,使用 Server-sent Events 就成为了一种非常好的替代方案。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6594ca71eb4cecbf2d90eab2


纠错反馈