Server-Sent Events (SSE) 是一种服务器向客户端推送事件的机制,用于实时交互。在前端领域,SSE 可以方便地实现数据的实时推送、在线聊天、股票 ticker 等场景。而 Node.js 做为后端语言,提供了 SSE 的实现方式,但在使用过程中可能会遇到各种异常情况,本文将介绍 Node.js SSE 的异常处理方式。
SSE 基本使用
在 Node.js 中,通过 EventSource
实例来接收 SSE。如下所示:
const eventSource = new EventSource('/sse'); eventSource.onmessage = (event) => { console.log(`Message received: ${event.data}`); };
客户端代码非常简单,在服务端,也很容易实现 SSE,只需要发送符合 SSE 规定的信息即可。下面是一个简单的 SSE 服务器示例:
-- -------------------- ---- ------- ----- ---- - ---------------- ----------------------- ---- -- - ------------------ - --------------- -------------------- ---------------- ----------- ------------- ------------ --- -------------- -- - ---------------- ----- -------------- -- ------ ----------------
这个服务器每隔一秒钟就会向客户端推送一条数据,客户端就可以通过 EventSource
实例接收到这些数据了。但是,实际使用中,我们需要处理一些异常情况。
异常处理
前后端连接异常
由于网络问题,前后端连接可能会出现异常,这时候我们要做的是检查异常并重新建立连接。我们可以在 EventSource
实例上绑定 error
事件来监听异常。如下所示:
-- -------------------- ---- ------- ----- ----------- - --- -------------------- ------------------------------------- ------- -- - ----------------------- ---------- -------------------- ------------- -- - ---------------- -- ------------- ----- -------------- - --- -------------------- ------------------------ - -- -- - ---------------------------- ----------- - --------------- -- -- ------ ---
这个代码段中,我们在 error
事件里检查到异常,就关闭当前的 EventSource
实例并重新建立连接。这里为了演示方便,我们只是过了五秒钟后重新建立连接,实际使用中可以需要更加细致的处理。
服务端关闭 SSE
有时候我们可能会手动关闭 SSE 服务(比如重启服务器)。这种情况下,EventSource
实例会持续尝试连接,但连接始终失败,并且不会触发 error
事件或其他事件。为了避免连接池中有过多的连接失败,我们需要额外处理这种异常情况。
我们可以在服务端手动关闭 SSE 时,下发 204 No Content 状态码,同时关闭连接,如下所示:
// 关闭 SSE 服务 res.writeHead(204, { // ... }); res.end();
在客户端可以通过在 EventSource
实例上增加 204
事件来捕捉这种异常情况,如下所示:
const eventSource = new EventSource('/sse'); eventSource.addEventListener('204', (event) => { console.log('Server Close SSE.'); eventSource.close(); });
这种方式可以减少不必要的连接尝试,避免因为服务端异常而给客户端带来的额外费用。
总结
在 Node.js SSE 实际使用中,我们需要注意异常情况处理。本文介绍了在前后端连接异常和服务器主动关闭 SSE 时的处理方式。它们可以避免不必要的连接保持和异常情况的损失,提高 SSE 使用的可靠性。
参考资料:
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/647c7722968c7c53b077f962