前言
在很多 Web 应用中,我们需要实时地向客户端推送数据。例如,社交网络中的消息通知、在线聊天室、股票行情等等。传统的实现方式是使用轮询(Polling)或长轮询(Long Polling),这些方式都需要客户端不断地发起请求,服务器才能返回最新的数据。这种方式的缺点是浪费带宽和服务器资源,同时也会增加服务端的负担。
Server-Sent Events(SSE)是 HTML5 中的一种新技术,它提供了一种更加高效的实时数据推送方式。使用 SSE,服务器可以主动向客户端发送数据,而不需要客户端不断地发起请求。本文将介绍两种最简单牢靠的方式来实现基于 SSE 的推送机制。
SSE 简介
SSE 是一种基于 HTTP 的服务器推送技术,它使用了一种特殊的 HTTP 响应格式,即 text/event-stream。SSE 的工作原理如下:
- 客户端向服务器发送一个普通的 HTTP 请求。
- 服务器返回一个 text/event-stream 格式的响应,其中包含了一个或多个事件。
- 客户端收到响应后,解析其中的事件并进行相应的处理。
- 服务器可以在任何时候向客户端发送新的事件,客户端也可以在任何时候关闭连接。
实现方式一:使用 EventSource 对象
EventSource 是 HTML5 中提供的一种用于接收 SSE 数据的 JavaScript 对象。使用 EventSource 对象,我们可以很容易地实现基于 SSE 的推送机制。
服务端代码
以下是一个使用 Node.js 实现 SSE 的示例代码:
-- -------------------- ---- ------- ----- ---- - ---------------- ----------------------- ---- -- - ------------------ - --------------- -------------------- ---------------- ----------- ------------- ------------ --- -------------- -- - ----- ---- - --- ---------------------- ---------------- -------------- -- ------ ----------------
上述代码中,我们使用 Node.js 创建了一个 HTTP 服务器,并在其中实现了 SSE 的推送机制。其中:
- 在响应头中设置了 Content-Type 为 text/event-stream,这告诉浏览器这是一个 SSE 的响应。
- 设置了 Cache-Control 为 no-cache,这告诉浏览器不要缓存这个响应。
- 设置了 Connection 为 keep-alive,这告诉浏览器保持连接不要关闭。
我们使用 setInterval 函数每隔一秒向客户端发送一个事件,事件的内容为当前的时间字符串。
客户端代码
以下是一个使用 EventSource 对象接收 SSE 数据的示例代码:
const source = new EventSource('http://localhost:8080'); source.addEventListener('message', (event) => { const data = event.data; console.log(data); });
上述代码中,我们创建了一个 EventSource 对象,并指定了 SSE 数据的来源。然后,我们使用 addEventListener 函数监听 message 事件,并在事件处理函数中打印出事件的数据。
指导意义
使用 EventSource 对象实现 SSE 的推送机制非常简单,代码量也很少。但是,需要注意以下几点:
- SSE 只能使用 HTTP 协议,不能使用 HTTPS 协议。
- SSE 的数据格式必须是 text/event-stream,否则浏览器将无法正确解析。
- SSE 的数据必须以 data: 开头,以两个换行符结尾,否则浏览器将无法正确解析。
实现方式二:使用 WebSocket 协议
WebSocket 是一种全双工的通信协议,它可以在客户端和服务器之间建立一个持久的连接,实现实时数据的推送。使用 WebSocket,我们也可以很容易地实现基于 SSE 的推送机制。
服务端代码
以下是一个使用 Node.js 实现 WebSocket 的示例代码:
-- -------------------- ---- ------- ----- ---- - ---------------- ----- --------- - -------------- ----- ------ - -------------------- ----- --- - --- ------------------ ------ --- -------------------- ---- -- - -------------- -- - ----- ---- - --- ---------------------- -------------- -- ------ --- --------------------
上述代码中,我们创建了一个 HTTP 服务器和一个 WebSocket 服务器。在 WebSocket 的 connection 事件中,我们使用 setInterval 函数每隔一秒向客户端发送一个时间字符串。
客户端代码
以下是一个使用 WebSocket 对象接收数据的示例代码:
const ws = new WebSocket('ws://localhost:8080'); ws.onmessage = (event) => { const data = event.data; console.log(data); };
上述代码中,我们创建了一个 WebSocket 对象,并指定了数据的来源。然后,我们使用 onmessage 函数监听 message 事件,并在事件处理函数中打印出事件的数据。
指导意义
使用 WebSocket 实现 SSE 的推送机制同样非常简单,但是需要注意以下几点:
- WebSocket 的数据格式可以自定义,不需要遵循 SSE 的格式要求。
- WebSocket 的连接可以使用 HTTP 或 HTTPS 协议。
- WebSocket 的连接需要服务器端和客户端都支持,如果服务器端不支持 WebSocket,客户端将无法建立连接。
结论
SSE 是一种高效的实时数据推送方式,使用 EventSource 对象和 WebSocket 协议都可以很容易地实现基于 SSE 的推送机制。使用 SSE 可以减少浪费的带宽和服务器资源,提高 Web 应用的性能和用户体验。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6743ce4af3dd65303298bae8