使用 Server-sent Events 构建实时酒店房间预订系统

阅读时长 13 分钟读完

在现代互联网应用中,实时的数据更新对于用户体验和功能的完善都非常重要。在创建一个酒店预订系统中,实时的房间更新和预订信息是不可或缺的。然而,实现实时数据更新不是一个简单的任务。传统的 Ajax 调用和长轮询都具有一定缺陷,其中轮询还会造成服务器开销增加。在这种情况下,Server-sent Events (SSE,服务器推送事件) 是一种更为有效的实时数据更新解决方案。

什么是 Server-sent Events?

Server-sent Events 是 HTML5 规范中的一部分。它提供了一种浏览器与服务器通信的方式,允许服务器推送事件到客户端。也就是说,在客户端收到服务器发送的消息时,不需要轮询或者 Ajax 调用服务器,而是通过 SSE 连接自动接收数据流。

SSE 协议具有以下主要特点:

  1. 双向通信。SSE 协议是由浏览器发起的,服务端不能主动连接浏览器。只有浏览器和服务器建立 SSe 连接后,服务器才能向浏览器发送事件。
  2. 持久连接。SSE 协议与传统的 HTTP 请求不同,其请求的连接资源不随着请求结束而关闭,而是一直保持打开的状态,直到客户端或者服务器端主动关闭它。
  3. 自动重连。由于网络噪声或服务器故障等原因,SSE 连接可能会关闭。在这种情况下,浏览器会自动重新连接服务器,保证数据传输不会中断。

为什么选择 Server-sent Events?

在传统的 Ajax 方式中,客户端不停地轮询服务器,这样会浪费带宽和宝贵的服务器资源,并且在实时更新数据时,延迟高、实时性差。而使用 Server-sent Events 则可以避免这种情况发生,它具有以下优点:

  1. 减少服务器负担。SSE 协议会在客户端和服务器之间建立一条持久连接,服务器不需要再单独为每一个客户端进行请求处理。
  2. 实时性强。在客户端收到服务器推送的消息后,无需等待,即可及时响应并更新数据,可以很好地提升用户体验。
  3. 跨域支持。SSE 协议可以与跨域的服务器进行连接,并能够接收来自跨域服务器的事件推送。

如何使用 Server-sent Events?

下面我们将演示如何使用 SSE 构建实时酒店房间预订系统,这里我们将使用 Node.js 搭建服务器端环境。

建立 SSE 连接

客户端与服务器建立 SSE 实时连接之前,需要先通过 EventSource 对象来创建事件源,该对象可以在具有 SSE 协议的 URL 上进行访问,用于接收服务器发送过来的消息。

在上述代码中,'/sse' 是服务器 SSE 推送事件的路由。通过创建一个 EventSource,即可建立 SSE 连接并监听服务器发送过来的数据消息。

服务器端设置 SSE 监听

在服务器端,我们需要为客户端建立一个 SSE 监听器,以推送 SSE 事件。接下来,我们通过 Node.js 和 Express 来演示建立一个 SSE 连接的方法。

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

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

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

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

在上述代码中,我们使用 Express 的 app.get() 方法建立了一个 SSE 监听器,当客户端访问 SSE 路由时,服务器向客户端推送一个 'hello world' 的事件。服务器端每隔 2 秒,向客户端发送一条数据,这个时间间隔可以根据业务需求来调整。

每次服务器发送数据时,我们需要在消息开头添加 "data:" 字符串,以表明这是一个 SSE 事件消息,然后添加两个换行符 '\n\n',以表明消息已完成。客户端会解析数据,忽略 "data:" 字符串,并在两个换行符之间提取数据内容。

监听 SSE 事件

当 SSE 监听器与客户端建立连接之后,服务器便可以随时向客户端推送消息。所有消息都通过 EventSource 对象的 onmessage 事件监听,当服务器有新的数据事件发送时,该事件会被触发。

在上述代码中,我们建立了一个 SSE 连接,当有数据事件被推送时,将在浏览器控制台上输出接收到的消息内容。

现在我们已经了解了如何使用 Server-sent Events 进行双向通信,以下是如何使用 SSE 构建实时酒店房间预订系统的示例代码。

服务器端

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

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

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

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

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

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

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

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

在上述代码中,我们使用了一个存储客房信息的数组来模拟数据,并将其定时发送到客户端。同时,我们通过发送 SSE 事件,将这个订单信息实时推送到客户端。

客户端

客户端的代码主要包括渲染页面和建立 SSE 连接两部分,以下是示例代码。

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

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

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

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

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

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

在客户端代码中,我们使用 EventSource() 的方法来创建一个 SSE 连接,并监听 'message' 事件。当事件发生时,调用相应的回调函数来更新页面内容。

我们还实现了 addReservation() 函数, which adds a new reservation to the reservation list on the client side。the updateRooms() 和 updateReservations() 函数将房间和订单列表清空,然后根据服务器返回的数据来更新它们。最后,在提交订房表单后,使用 fetch API 向服务器端发送一个 POST 请求,并将返回的数据添加到预订列表中。

总结

本文详细介绍了如何使用 Server-sent Events(SSE)来构建一个实时的酒店房间预订系统。通过使用 SSE 协议,我们可以实现双向通信,减少服务器负面,提高实时性,允许跨域连接等功能。

建立 SSE 连接的步骤很简单。在客户端,我们使用 EventSource 对象来连接服务器端,并监听 'message' 事件以接收服务器发送过来的消息。在服务器端,我们需要建立一个 SSE 监听器,并将更新的数据通过 SSE 事件推送给客户端。在这种实时应用场景下,Server-sent Events 可以作为一种理想的解决方案。

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

纠错
反馈