SSE 使用中的坑:浏览器异常断开请求和 WebSocket 并用等

简介

SSE(Server-Sent Events)是一种轻量级的服务器推送技术,允许 Web 服务器向浏览器发送数据,实现了服务器与前端的实时数据交互。相较于 WebSocket,SSE 的实现更为简单,且不需要多线程编程技能,可以方便地使用在各种 JavaScript 应用程序中。

但在使用 SSE 技术时,存在一些坑点,常见的问题是浏览器异常断开请求和 WebSocket 并用等。本文将详细介绍这些问题并提供相应的解决方法

浏览器异常断开请求

SSE 可以无限期地发送数据,但是浏览器可能会在某些情况下终止请求,例如网络中断、关闭页面等,SSE 本身无法有效地处理这种情况,因此需要应用特定的机制来应对。

SSE 的心跳机制

SSE 的心跳机制是保证 SSE 持续连接的一种机制,其原理是在服务器端定时发送一个固定内容的消息,用于检查客户端是否需要保持连接。如果客户端一段时间内未收到消息,则认为连接已经断开。

以下是一个 SSE 心跳机制的示例代码:

服务端:

--- --------- - --- -----------------

-------- ------------ ---- -
  --- -- - --

  -- ------
  ------------------ -
    --------------- -------------------- -- -----
    ---------------- -----------
    ------------- -------------
    ------------------------------ ---
  ---

  -------------- -- -
    --- ----------- - --- -----------------
    -------------- ------------
    ----------------- ---------
    ---------------- ------------- - -----------------
  -- ------
-

------------------ ---------

客户端:

--- --- - --- ------------------------

------------- - --------------- -
  ------------------------
--

----------- - ---------- -
  ----------------------- ---------
--

其中,客户端通过 EventSource 构造函数指向服务端的 /sseTest 路径,接收 SSE 事件。服务器定时地向客户端发送固定内容的消息,从而检测连接是否断开,客户端在 onError 事件中处理连接已经断开的情况。

定期重新连接

除了心跳机制以外,定期重新连接也是一种较为常见的处理 SSE 异常断开连接的方法。在客户端连接断开时,重新发送连接请求,实现 SSE 服务的持续连接。

以下是一个定期重新连接的代码示例:

--------- --------- -
  --- ------ - --- ------------------------

  ---------------- - --------------- -
    ------------------------
  --

  -------------- - ---------- -
    ----------------------- ---------
    ------------------- ------
  --
-----

该方法适用于服务器端不强制关闭客户端连接的场景,可以用于实现自动重连,并保持前端页面的实时更新。

WebSocket 并用等

WebSocket 与 SSE 在实现上有很多相似之处,但是其确实是一种双向通信的机制,相较于 SSE 更加灵活,可以用于实现多种不同的服务端应用,例如多人在线游戏等。

但是在实际应用中,我们常常会遇到 WebSocket 与 SSE 的并用场景,包括在不同的浏览器中以及环境中使用 WebSocket 并用 SSE 等。在这种情况下,我们需要将 SSE 与 WebSocket 结合起来,以实现更强大、更可靠的数据推送机制。

SSE 与 WebSocket 并用的优缺点

SSE 和 WebSocket 都可以用于实现服务端与浏览器的实时数据交互,但是两种技术各自存在着优缺点,需要针对具体需求进行选择。

SSE 的优点:

  • SSE 可以被广泛支持,因为它只使用了 HTTP 协议;
  • SSE 可以携带不同的数据流,比 WebSocket 更灵活;
  • SSE 不需要额外的协议解析,因此在处理服务端数据时速度更快;

SSE 的缺点:

  • SSE 只能由服务端向客户端推送数据,不支持双向通信;
  • SSE 可能会遭受到浏览器网络故障或者链接断开的影响。

WebSocket 的优点:

  • WebSocket 是双向的,服务端和浏览器都可以随意地推送和获取数据;
  • WebSocket 通信协议是二进制的,因此与 SSE 相比,速度更快且适合处理大量数据。

WebSocket 的缺点:

  • WebSocket 只能在部分浏览器上使用;
  • WebSocket 的协议需要特定的解析。

SSE 与 WebSocket 并用的示例代码

以下是一个使用 SSE 与 WebSocket 并用的代码实例,该实例使用了 Node.js 和 Express。

服务端:

----- ------- - -------------------
----- ---- - ----------------
----- --------- - --------------
----- --- - ----------

-- --- --
--- -------------- - ---

-------- -------- ---- -
  ----- ---------- - -
    --- -----------
    --------- ---
  -
  ------------------ -
    --------------- --------------------
    ---------------- -----------
    ------------------------------ ----
    ------------- ------------
  ---
  --------------------------------
  --------------- -- -- -
    ---------------- ---------- ---- - --- -------------------
    -------------- - ------------------------- -- ------ --- ---------------
  ---
-

-- --------- --
----- ------ - -----------------------
----- --------------- - --- ------------------ ------ ---

-------------------------------- -------- ---- -- -
  ---------------------- ------------

  ------------------ -- -- -
    ---------------------- --------------
  ---
---

-- ------------- ----
--- ----- - --
-------------- -- -
  --------
  -------------------- ------- --- --- --- ---------- -----------
  -------------------------- -- -
    ----- ---- - ------ --------------
    -------------------------
  ---
  -------------------------------------- -- -
    -- ------------------ --- --------------- -
      --------------------------------- ---------
    -
  ---
-- ------

------------------ -----

------------------- -- -- -
  ------------------- --------- -- ---- -------
---

客户端:

--------- -----
------
  ------
    ---------------- - --- ------------
  -------
  ------
    ------------- - --- ---------
    ------- ----------
    ---- -----------------------

    ------------- ----------
    ---- ------------------------------

    --------
      ----- ------- - ------------------------------------
      ----- ------------- - -------------------------------------------

      ----- --- - --- -----------------------
      ------------- - ------- -- -
        ----------------- - -------------
      -

      ----- --------- - --- ---------------------------------
      ------------------- - ------- -- -
        ----- ---- - -------------------------
        ----------------------- - ----------
      -
    ---------
  -------
-------

在该示例中,我们在服务端同时使用了 SSE 和 WebSocket 技术,通过定期向客户端推送数据,实现了 SSE 和 WebSocket 并用的效果,同时在客户端使用了 SSE 和 WebSocket 的不同 API,将两者的数据展示在页面上。

结论

本文介绍了 SSE 的心跳机制和定期重新连接方法,作为 SSE 异常断开连接的解决方案,并介绍了 SSE 与 WebSocket 并用的优缺点和代码示例。掌握这些技术,能大幅度提升服务端与前端实时数据交互的效率,对于前端开发者来说有很高的学习和指导意义。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/67088579d91dce0dc871fd9e