背景
Server-Sent Events(SSE)是 HTML5 中一种常见的实现服务器推送消息至浏览器的技术。在使用 SSE 时,浏览器向服务端发送一个请求,服务端将 response stream 保持开启,并在需要时将新的事件推送至浏览器端。这种技术在实时性要求高的应用场景(如聊天室、股票行情)中非常实用。
然而,当服务端将 response 缓存时,可能会导致 SSE 推送消息出现延迟。本文将介绍这个问题的原因和解决方案。
分析
在向客户端传输数据时,服务端可能会设置 response 缓存。在传统的请求-响应模式下,response 缓存可以优化浏览器性能,但在 SSE 中,会导致延迟问题。
因为 SSE 借助了浏览器的 EventSource 接口,而 EventSource 只能通过关闭连接来判断消息是否推送完毕。当服务端将 response 缓存时,每次请求都会得到之前缓存的数据,甚至在服务端有新消息推送时也是如此。因此,浏览器得不到所期望的数据推送,从而导致延迟问题的产生。
解决方案
为了避免上述问题,我们需要关闭 response 缓存。最简单的方式是在服务端的响应头中设置 Cache-Control 和 Pragma 字段。例如:
res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Pragma', 'no-cache');
这将告诉浏览器不要缓存 response。而服务端每次推送新消息时,浏览器也会得到最新的数据,确保延迟问题得以解决。
示例代码
下面是一个基于 Node.js 的 SSE 示例代码。该代码使用 Express 框架搭建,通过设置响应头来禁用 response 缓存。服务端每秒钟向客户端推送当前的时间。客户端则将推送的消息打印到控制台中。请注意其中的缓存设置。
服务端代码:
-- -------------------- ---- ------- ----- ------- - ------------------- ----- --- - ---------- --------------- ----- ---- -- - ----------------------------- --------------------- ------------------------------ ------------ ----------------------- ------------ -------------------------------------------- ----- -------------- -- - ----- ---- - ------ ----- ---------------------------------- ---------------- -- ------ --- ---------------- -- -- ---------------- ------ ------- -- ---- --------
客户端代码:
const es = new EventSource('http://localhost:3000/sse'); es.addEventListener('message', (event) => console.log(event.data));
结论
SSE 是一种实现服务器推送消息至浏览器的有效技术。然而,在使用 SSE 时,如果服务端开启了 response 缓存,将导致消息推送出现延迟。为了避免这种情况,服务端需要在响应头中明确禁用 response 缓存。这是保证 SSE 实时性的基本要求,值得后端工程师在实际开发中重视和实践。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67113f64ad1e889fe2fe3285