在 Express 中使用 Server-Sent Events 实现实时通信

引言

在前端开发中,实时通信是一个非常重要的功能。一般情况下,我们使用 WebSocket 或 SockJS 来实现实时通信。但是,如果你只需要一个简单而轻巧的解决方案,那么使用 Server-Sent Events(SSE)是一个不错的选择。

本文将介绍如何在 Express 中使用 SSE 实现实时通信。我们将从介绍 SSE 的基本概念开始,然后深入讲解如何在 Express 中实现 SSE,最后展示一个完整的示例代码。

SSE 简介

Server-Sent Events 是一种典型的事件流协议。客户端通过 HTTP 连接到服务器,并保持长连接,服务器会定期发送新的数据给客户端。与 WebSocket 不同的是,SSE 仅支持从服务器到客户端的单向通信,也就是客户端不能向服务器发送数据。

SSE 允许在一个 HTTP 连接上按照事件流的形式发送文本数据。事件流以一个标识符开头,这个标识符定义了事件的类型。在这个事件类型之后,可以添加任意名称/值的属性。最后是一个空行,然后是数据本身。下面是一个 SSE 事件流的示例:

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

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

在这个例子中,我们定义了两个事件。第一个事件类型为“myEvent”,带有一个 ID 属性为“123”,数据为一个包含一个“hello”键和一个“world”值的 JSON 对象。第二个事件类型为“anotherEvent”,没有 ID 属性,数据是一个简单的字符串。

在 Express 中实现 SSE

要在 Express 中实现 SSE,我们需要使用一个名为 sendEvent 的中间件。该中间件将设置正确的响应头并启用响应流模式:

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

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

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

这个中间件使用 text/event-stream 来设置响应类型并设置 Cache-Control 和 Connection 响应头。然后,我们为每个新的 SSE 客户端创建一个新的客户端对象,并将其添加到用户列表中。最后,我们定义关闭事件处理程序,以便在客户端关闭连接时从用户列表中删除客户端对象。

接下来,我们可以定义一个路由处理程序,用于向 SSE 客户端发送事件。我们通过广播函数来同时向所有客户端发送事件:

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

我们使用 res.write 函数将数据发送到客户端。请注意,在数据后面添加了两个换行符,这是 SSE 事件流的一部分。

最后,我们可以定义一个路由来处理使用 SSE 的客户端的请求:

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

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

在这个路由处理程序中,我们使用 sendEvent 中间件来设置响应头并将客户端添加到客户端列表中。然后,我们使用 res.flushHeaders 函数确保响应头立即发送。接着,我们通过 broadcast 函数向所有客户端发送消息。

最后,我们设置一个间隔,每 2 秒向所有客户端发送一个新事件。当客户端关闭连接时,我们清除该间隔。

示例代码

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

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

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

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

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

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

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

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

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

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

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

结论

在本文中,我们介绍了 Server-Sent Events(SSE)的基本概念,并详细讲解了如何在 Express 中使用 SSE 实现实时通信。我们使用 sendEvent 中间件设置 SSE 响应头并将客户端添加到客户端列表中。然后,我们通过广播函数向所有客户端发送消息。最后,我们展示了一个完整的示例代码,演示了如何在 Express 中使用 SSE。

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