使用 SSE 实现服务器与多个客户端实时通信

阅读时长 6 分钟读完

什么是 SSE

Server-Sent Events(SSE)是 HTML5 标准中一种不同于 WebSockets 的服务器推送技术。它允许服务器向客户端发送自定义消息,并通过长连接保持实时通信。与 WebSockets 不同的是,SSE 采用基于 HTTP 协议的简单机制,可在现有基础网络架构上实现实时通信,更适用于单向通信的场景。

SSE 能够提供以下特性:

  • 易于实现和部署
  • 实时推送事件流
  • 支持自定义事件类型
  • 只需要一个 HTTP 连接

SSE 原理

SSE 依赖于 HTTP 协议上的长轮询(Long Polling)技术。当客户端接收 SSE 事件流后,它会保持打开的 HTTP 连接,用来等待服务器端提供的事件。如果服务器端暂时没有事件能够发送给客户端,客户端就会阻塞并保持长连接。一旦服务器端有了新的事件,它就能够立即推送到客户端,这些事件就能通过 HTTP 响应发送到客户端。

浏览器支持 SSE

目前,主流的现代浏览器都已经支持 SSE 技术,包括 Chrome、Firefox、Opera、Safari 以及 Android 和 iOS 等移动设备浏览器。只有 Internet Explorer 不支持它。对于 IE 浏览器,我们可以使用 polyfill 库(如 EventSource.js)来实现 SSE 的支持。

使用 SSE 实现实时通信

下面通过一个简单的示例,展示如何使用 SSE 实现一个服务端向多个客户端推送事件的功能。

实现一个 SSE 服务器

首先,我们需要创建一个 SSE 服务器来向客户端推送事件。在 Node.js 环境下,我们可以使用 express 和 EventSource 模块来实现。

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

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

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

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

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

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

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

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

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

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

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

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

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

这段代码主要是实现一个 HTTP 服务, 客户端通过 /events 路径来连接 SSE 服务器。在连接时,服务器会向客户端发送一些元数据,告知客户端如何处理响应。同时,我们还为每个连接生成了一个唯一的 clientId,这样我们才能知道连接来自哪个客户端。

在客户端连接成功后,我们还需要从 /stream/:clientId 路径生成一个 SSE 流来向客户端推送事件。在这个例子中,我们简单地每隔 3 秒向客户端推送一条消息。

实现一个 SSE 客户端

接下来,我们需要实现一个 SSE 客户端来接收来自 SSE 服务器的事件。在浏览器中,我们可以使用 EventSource 接口来和 SSE 服务器建立连接,并接收来自服务器的推送事件。

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

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

这个 HTML 页面在客户端打开后,会向 /events 路径发送一个 GET 请求,创建一个 EventSource 对象来建立 SSE 连接,并监听 message 事件来获取服务器发送的消息。当收到新消息时,我们将它添加到页面中的一个无序列表中。

运行项目

在终端中输入以下命令来运行 SSE 服务器:

在浏览器中打开以下 URL,我们就能看到 SSE 客户端的页面:

现在我们就能在 SSE 客户端的页面上看到我们向客户端推送的事件流了。

总结

通过以上这个简单的例子,我们已经实现了一个 SSE 服务器和 SSE 客户端,并能够向多个客户端推送实时事件。使用 SSE 技术,我们能够在浏览器中实现单向实时通信,同时又能够避免使用 WebSockets 所需的握手协议和通信开销。

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

纠错
反馈