使用 Server-Sent Events 实现实时数据推送

引言

在现代 Web 应用程序开发中,实时数据推送变得越来越重要。在过去,开发人员不得不通过 AJAX 长轮询或 WebSockets 来实现实时通信。不过, 这些方法对于实现简单的实时通信来说过于繁琐。Server-Sent Events(SSE)是一种轻量级的技术,可以轻松地实现服务器向客户端发送实时数据。

本文将介绍如何使用 SSE 在前端应用程序中实现实时数据推送。文章将涵盖 SSE 是什么、如何在前端使用 SSE、如何从服务器端进行 SSE 推送以及使用 JavaScript 编写 SSE 示例代码。

什么是 Server-Sent Events(SSE)?

Server-Sent Events(SSE)是一个 HTML5 API,可以在客户端和服务器之间建立单向连接。服务器可以通过这个连接不断地向客户端发送新数据,而无需进行客户端的请求。这使得 SSE 成为一个非常有用的技术,例如,可以在提示框中显示实时更新,获取最新的股票报价,或者在 Web 应用程序中收到及时的通知。

SSE 协议基于 HTTP,因此 SSE 消息可以通过任何 HTTP 服务器和客户端进行传输。SSE 消息采用文本格式(text/event-stream)并具有以下特点:

  • 单向传输,即服务器端向客户端发送信息
  • 所有数据都是文本格式
  • 使用“事件”(event)将消息分组

在 SSE 消息中,多个消息可以使用换行符分隔。每个消息通常由标题和正文组成。标题包括消息标识符、事件类型和可选的超时机制。

下面是一个 SSE 消息示例:

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

在这个示例中,id 是消息标识符,event 是事件类型,data 是消息的正文。\n 表示消息结束。

如何在前端使用 SSE?

使用 SSE 在前端应用程序中实现实时数据推送非常容易。只需要在前端添加一个事件侦听器来监听消息,并且通过 HTTP 请求来创建 SSE 连接即可。下面是一个简单的 ES6 类,用于处理 SSE 连接:

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

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

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

在这个示例中,SseClient 类接受一个 URL,该 URL 指示 SSE 服务器的位置。connect 方法使用 EventSource 类创建一个 SSE 连接,并侦听 message 事件来接收从服务器发送的消息。在接收到消息时,将执行提供的回调函数。

要使用 SseClient,只需在 Vue.js 项目中创建一个全局服务:

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

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

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

在这个示例中,我们将 SseClient 实例作为全局 Vue 服务注入到 Vue.prototype 中。我们还通过混合来销毁 SSE 连接。

最后,只需在 Vue.js 组件中使用 $sse.connect 来侦听 SSE 事件:

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

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

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

在这个例子中,我们将接收到的消息分配给组件实例中的 message 属性。此时,每当从服务器端发送 SSE 消息时,该组件都会接收到消息并在页面上显示。

如何从服务器端实现 SSE 数据推送?

要使用 SSE 在服务器和客户端之间发送实时数据,需要使用一个基于 HTTP 服务器的服务器端脚本。下面是一个 Node.js 脚本来实现 SSE 消息推送:

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

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

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

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

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

在这个例子中,我们创建了一个 Node.js HTTP 服务器,并注册了一个名为 /stream 的 SSE 端点。在 /stream 端点上,我们将响应头设置为 text/event-streamCache-Control 设置为 no-cache,并且Connection 设置为 keep-alive。然后,我们使用 setInterval 函数为客户端推送每秒一个 SSE 消息。当客户端连接断开时,我们清除 setInterval

在主页端点上,我们向客户端呈现了一个简单的 HTML 页面,用于接收来自 SSE 服务器的消息。

结论

Server-Sent Events 是一种轻量级的技术,可以轻松地实现服务器向客户端实时推送数据。在前端应用程序中,使用 SSE 可以通过一个简单的 ES6 类来处理 SSE 连接。在服务器端,任何 HTTP 服务器可以用于发送 SSE 消息。这使得 SSE 成为构建实时应用程序的理想选择。

服务器端 SSE 推送示例代码:https://github.com/dmnsgn/sse-example

前端 SSE 推送示例代码:https://codepen.io/hayden-george/pen/RLaYPp

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