在前端开发领域中,SSE(Server-Sent Events)是一种相对较新的技术,它可以使我们更好地处理服务器向客户端发送消息的场景,而无需使用 WebSocket。该技术能够帮助我们实现实时通信,让我们在处理实时数据和事件时事半功倍。但是,当遭遇断网或链接异常情况时,这些优势都可能会变得毫无意义。那么,SSE 如何应对这些情况,以保证良好的用户体验呢?
何时意识到链接发生异常
当使用 SSE 与服务器进行通信时,我们需要始终关注链接的健康状况。如果链接出现异常并无法恢复,那么客户端需要及时采取措施。我们可以通过以下三种方式,让客户端意识到链接异常发生:
1. 连接状态码
当 SSE 连接从服务器断开时,我们会收到一个关闭事件(onclose
)。在这个事件中,我们可以获取到一个状态码(event.code
)来判断连接是否正常关闭,以及分析异常的类型。
const source = new EventSource('/sse'); source.onclose = function(event) { console.log('SSE connection closed.'); console.log('status code:', event.code); };
常见的状态码如下:
- 1000:正常关闭
- 1001:服务器关闭
- 1002:协议错误
- 1003:数据错误
- 1004:保留代码
- 1005:无状态码
- 1006:无连接
以上状态码中,除了 1000(正常关闭)之外,其余均为异常情况。
2. 心跳机制
除了依赖 SSE 自身的关闭事件外,我们还可以通过发送心跳包检测链接是否存活。在客户端使用 SSE 与服务器保持长连接时,服务端会默认设置一个超时时间,在该时间内没有任何消息返回给客户端,链接将被关闭。我们可以在客户端定时发送一个空消息,模拟心跳机制,以保持链接持续存活。当我们长时间未能收到服务器的消息,那么这个心跳消息将会失败,我们就可以意识到链接已经断开。
-- -------------------- ---- ------- ----- ------ - --- -------------------- -- -- -- --------- ---------------------- - ------------------------ -------------------- -- ------- ------------------------------------ --------------- - -- ------ --- -------------- - --------------- - ---------------- ---------- ---------- --
通过这种方式,我们确保了客户端与服务端的链接处于活跃状态,并及时得知链接异常的情况。
3. 重新连接机制
当我们确定链接已经断开时,我们需要及时重新建立连接,以保证服务继续正常运行。在重新连接时,我们可以通过尝试多个 HTTP 请求进行尝试,直到连接成功或者达到一定限制次数(例如,连接 5 次后仍然失败,则不再继续尝试)为止。
-- -------------------- ---- ------- --- -------------- - -- -------- --------- - ----- ------ - --- -------------------- ---------------- - --------------- - ------------------------ -- -------------- - --------------- - ---------------- ---------- ---------- ------------------- ------- ------------ -- ------------- -- ----------- --- ----- - -- ---- - ----- -- --------------- - -- - ----------------- ---------------------------- ------------------- ------ - ---- - ---------------------- ---------- - - -- - ----------
断网应对方法
当用户断网或者服务端异常,SSE 链接会被关闭。如果我们能够及时采取措施,依旧可以保证用户体验良好。在上文中,我们介绍了如何通过重新连接机制来应对服务器异常的情况。但是,当用户断网,我们无法通过 SSE 连接来感知和处理异常,即使我们实现了心跳机制也无法保证联系的可靠性。
这时候,我们可以通过改变 SSE 连接的 url 进行周期性的重新连接操作(也称轮询)。例如,我们可以在设置 SSE 连接前,先检查一下网络状态,如果网络良好,则直接建立 SSE 连接;如果网络不佳,则通过轮询机制进行周期性的链接尝试。轮询的时间可以根据实际情况来设置,但是不建议过于频繁,以防影响性能。
-- -------------------- ---- ------- -------- --------- - ----- ------ - --- -------------------- ---------------- - --------------- - ------------------------ -- -------------- - --------------- - ---------------- ---------- ---------- ------------------- ------- ------------ -- ------------- -- ----------- --- ----- - -- ----------- ------------------ ---------- ------- - -- - -------- ------ - ----- --- - --- ----------------- --------------- --------- ---------- - ---------- - ------------------------------ -- --------- --- -- ------------------ --------- ---------- -- ----------- - ---------- - -------------------- --------- ---------------- ------ -- ----------- - -- -- --- -- ----------
以上代码实现了断网应对的两种情况:一种是服务端异常使用重新连接机制,一种是网络异常使用轮询机制来检测网络恢复。
总结
在使用 SSE 进行实时通信时,我们需要注意链接是否处于正常状态。通过状态码、心跳机制、重新连接机制以及轮询机制等手段,我们可以充分利用 SSE 技术,确保链接的健康情况和实时通信的顺畅进行。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e15b4ef6b2d6eab3c839b9