如何在 Node.js 中实现 Server-Sent Events

阅读时长 7 分钟读完

如何在 Node.js 中实现 Server-Sent Events

Server-Sent Events (SSE)是一种用于实现服务器到客户端单向实时通信的技术。SSE 可以让服务器主动向客户端发送实时更新的数据,而无需客户端发起请求。

本文将介绍如何在 Node.js 中实现 SSE,包括如何创建 SSE 服务器、如何发送 SSE 数据以及如何在客户端接收 SSE 数据。我们将从概念上讲解 SSE 工作原理,并提供一个实际的实现示例。

SSE 工作原理

在 SSE 中,服务器使用 HTTP 长连接向客户端发送数据。客户端基于HTTP协议在浏览器端使用 EventSource API 来接收实时数据。一旦客户端与服务器建立连接,服务器便可以向客户端发送多个数据包,每个数据包都是使用一种特殊的格式发送的。该数据格式如下:

每个数据包都以 event::data 开头,后面是对应的数据。其中 event是可选的,如果没有提供,就默认将该事件称为 "message"。

将这些数据打包成一个流并传输到客户端,客户端可以在浏览器中使用 EventSource API 来接收这些数据。每当服务器发送新数据包时,客户端会在相应的回调函数中收到通知,并且可以处理收到的数据。

实现 SSE 服务器

首先,我们需要创建一个 HTTP 服务并将其作为 SSE 服务器。以下是一个基本的 SSE 服务器的示例代码:

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

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

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

----------------
展开代码

在这个示例代码中,我们使用 Node.js 内置的 http 模块创建了一个 HTTP 服务器。然后,我们设置了一些 SSE 特定的 HTTP 响应头,并向客户端发送了一个 SSE 数据包(本例中每秒钟一个)。

write 时,我们使用了格式化文本 : 的方式来区分事件和数据。注意,每条消息都必须以空字符串结尾,以便将其作为完整的消息处理。

在此示例中,我们没有将 SSE 客户端的连接存储在任何地方。这意味着,每当 SSE 客户端连接到该服务器时,都会为其创建新的连接。这是一种非常简单、低效的方法,但它可以起到说明 SSE 工作原理的作用。

向 SSE 客户端发送 SSE 数据

现在,我们需要让 SSE 服务器有能力向客户端发送 SSE 数据。以下是代码示例:

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

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

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

----------------
展开代码

在这个示例中,我们使用 setInterval 函数每秒钟向客户端发送一次 SSE 数据。每次都发送一个事件名称(在本例中为 message),以及当前时间作为数据。每条消息都必须以空字符串结尾,并使用 flush 函数将其刷新到客户端。

通过使用 SSE,服务器可以发送各种类型的数据,如事件,通知和数据。这使得 SSE 成为 Web 应用程序中各种实时和事件通信场景的绝佳选择。

向 SSE 客户端发送自定义事件

最后让我们把这些知识应用到实际情景中。在次,我们将示例代码替换为一个简单的聊天室。

服务端代码:

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

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

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

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

----------------
展开代码

在上面的代码中,我们使用了一些新的函数。当客户端向服务器发送数据时,req.on('data', (chunk) => {...}) 会响应数据事件,并接收客户端发送的数据。

客户端代码:

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

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

      --------------------------------------------------------- ------- -- -
        -----------------------
        ----- --- - --- -----------------
        ---------------- -----
        ------------------------------------ ----------------------------
        --------------------
        --------- - ---
      ---
    ---------
  -------
-------
展开代码

在客户端代码中,我们首先创建了一个 EventSource 实例,并将其连接到我们刚刚创建的 SSE 服务器。服务器一旦向 EventSource 实例发送数据,客户端就会收到该数据。

在聊天室中,我们在 <form> 元素上注册了 submit 事件,通过在提交事件上阻止默认行为来捕获表单的提交事件。然后,客户端使用 XMLHttpRequest 发送SSE消息到服务器,在向服务器发送完消息后,需要清空文本框。

结尾

在本文中,我们学习了如何在 Node.js 中实现 SSE,创建 SSE 服务器和客户端样本代码 参数的基础知识。SSE 非常适合在 Web 应用程序中实现实时通信和事件流。为了更好的学习 SSE,你可以进一步扩展本文示例代码,例如:

  • 实现可多个 SSE 客户端连接,存储所有客户端连接并向所有打开的连接发送数据包。
  • 将 SSE 服务器连接到一些实际数据源,例如数据库或远程 API,并使用 SSE 将数据以实时流方式推送到客户端。

如果你有关于 SSE 的任何问题和建议,请在评论区下方与我们分享。

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

纠错
反馈

纠错反馈