在传统的 web 应用程序中,Web 浏览器发送请求到服务器,服务器返回响应,然后关闭连接。这种方式限制了我们向浏览器推送实时数据的能力。然而,随着互联网应用程序的演化和用户对实时性的需求增加,这种方式已经变得过时了。另外,长轮询和 WebSocket 这些技术在某些情况下也存在缺陷,比如多个客户端同时拉取同一个数据时会增加服务器负担。为了应对这种情况,Server-sent Events (SSE) 技术应运而生。
Server-sent Events 是一种技术,它允许服务器实时地向客户端推送数据。客户端可以通过 EventSource API 来连接到服务器,并监听来自服务器的消息。当服务器向客户端推送消息时,客户端会自动处理这些消息而无需发送多次 Ajax 请求。基于 HTTP 协议,SSE 具有很高的兼容性。相较于 WebSocket,SSE 只需要建立一次连接,因此更容易部署和维护。
如何使用 Server-sent Events?
使用 Server-sent Events 可以分为两个部分:服务器和客户端。服务器需要返回一个带有 Content-Type: text/event-stream
头信息的 HTTP 响应,这样客户端才能将响应解析成事件流。在服务器端,我们首先要对请求的头信息做出响应:
const headers = { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }; response.writeHead(200, headers);
然后,我们需要将要发送的数据封装成事件形式发送给客户端:
response.write(`data: ${message}\n\n`);
其中,data:
是标准的 SSE 数据格式,它之后的内容是我们要发送的消息。这里的消息可以是任何形式的数据,比如一个 JSON 对象或者一个字符串。
在客户端,我们可以通过以下方式连接到服务器:
const source = new EventSource('/event-stream');
这里的 /event-stream
就是服务器的地址。然后我们可以监听 message
事件来处理服务器推送的消息。
source.addEventListener('message', function(event) { const message = event.data; // 处理服务器推送的消息 });
示例代码
下面是完整的 Server-sent Events 示例代码,展示如何连接到服务器并监听推送的消息:
服务器端代码:
-- -------------------- ---- ------- ----- ---- - ---------------- ----- ------ - --------------------------- --------- -- - -- ------------ --- ---------------- - ----------------------- - --------------- -------------------- ---------------- ----------- ------------- ------------ --- -------------- -- - ----- ------- - ---- ---- -- ----- ------------------------------ --------------------- ----------------- -- ------ - ---- - ------------------------ --------------- - --- --------------------
客户端代码:
const source = new EventSource('/event-stream'); source.addEventListener('message', function(event) { const message = event.data; console.log(message); });
总结
Server-sent Events 技术为发送实时数据提供了一个高效且易于部署的解决方案。相较于传统的轮询和 WebSocket 技术,SSE 更加轻巧,易于维护,且具有更好的兼容性。虽然目前还没有像 WebSocket 一样成熟的开发库,但我们相信它将成为未来 Web 应用程序实时数据通信的首选方案之一。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64608b7e968c7c53b02398dc