Node.js SSE 模块推送空数据坑点

阅读时长 3 分钟读完

介绍

Server-Sent Events(SSE)是一种现代化的 Web 技术,通过 HTTP 连接被动地推送数据到客户端,也是一种单向传输的技术。Node.js 的 SSE 模块也极为方便,通过无阻塞(非阻塞 I/O)推送数据,具有实时性和高效性。但是,Node.js SSE 模块推送空数据时存在浏览器超时的问题。本文主要介绍如何防止此问题的发生。

原因分析

客户端使用 EventSource 对象连接服务器,当没有数据发送时,EventSource 对象设置的超时时间到达后,将立即断开请求并触发浏览器超时。如果每次推送都检查数据是否为空,这样的处理方式将大大降低效率。

解决方案

心跳数据

解决方案一是每隔一段时间生成一条心跳数据用于向客户端推送,以保证连接持续性。例如,下面代码中,setTimeout 中 5 秒间隔生成心跳数据:

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

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

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

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

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

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

该示例每隔 5 秒钟发送一条字符串“heartbeat”。但这种方式会占用带宽,所以我们需要进行第二方案修改。

切断连接

解决方案二是在前一个事件发送完数据之后,检查新事件的数据是否为空。如果为空,就关闭和客户端的连接,以防触发浏览器超时。例如,下面代码中,当没有数据时,关闭链接:

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

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

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

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

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

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

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

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

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

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

该示例在每次推送事件时,先检查数据是否为空,如果是空,则直接结束 SSE 连接,以此达到防止触发浏览器超时的目的。

总结

在使用 Node.js SSE 模块时,需要注意空数据问题,否则将会引发浏览器超时问题。通过第一种方案实现心跳机制或第二种方案关闭不合规的连接,可以避免此类问题的发生。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64a64cb848841e98942e69bb

纠错
反馈