在现代互联网应用中,实时的数据更新对于用户体验和功能的完善都非常重要。在创建一个酒店预订系统中,实时的房间更新和预订信息是不可或缺的。然而,实现实时数据更新不是一个简单的任务。传统的 Ajax 调用和长轮询都具有一定缺陷,其中轮询还会造成服务器开销增加。在这种情况下,Server-sent Events (SSE,服务器推送事件) 是一种更为有效的实时数据更新解决方案。
什么是 Server-sent Events?
Server-sent Events 是 HTML5 规范中的一部分。它提供了一种浏览器与服务器通信的方式,允许服务器推送事件到客户端。也就是说,在客户端收到服务器发送的消息时,不需要轮询或者 Ajax 调用服务器,而是通过 SSE 连接自动接收数据流。
SSE 协议具有以下主要特点:
- 双向通信。SSE 协议是由浏览器发起的,服务端不能主动连接浏览器。只有浏览器和服务器建立 SSe 连接后,服务器才能向浏览器发送事件。
- 持久连接。SSE 协议与传统的 HTTP 请求不同,其请求的连接资源不随着请求结束而关闭,而是一直保持打开的状态,直到客户端或者服务器端主动关闭它。
- 自动重连。由于网络噪声或服务器故障等原因,SSE 连接可能会关闭。在这种情况下,浏览器会自动重新连接服务器,保证数据传输不会中断。
为什么选择 Server-sent Events?
在传统的 Ajax 方式中,客户端不停地轮询服务器,这样会浪费带宽和宝贵的服务器资源,并且在实时更新数据时,延迟高、实时性差。而使用 Server-sent Events 则可以避免这种情况发生,它具有以下优点:
- 减少服务器负担。SSE 协议会在客户端和服务器之间建立一条持久连接,服务器不需要再单独为每一个客户端进行请求处理。
- 实时性强。在客户端收到服务器推送的消息后,无需等待,即可及时响应并更新数据,可以很好地提升用户体验。
- 跨域支持。SSE 协议可以与跨域的服务器进行连接,并能够接收来自跨域服务器的事件推送。
如何使用 Server-sent Events?
下面我们将演示如何使用 SSE 构建实时酒店房间预订系统,这里我们将使用 Node.js 搭建服务器端环境。
建立 SSE 连接
客户端与服务器建立 SSE 实时连接之前,需要先通过 EventSource 对象来创建事件源,该对象可以在具有 SSE 协议的 URL 上进行访问,用于接收服务器发送过来的消息。
const source = new EventSource('/sse');
在上述代码中,'/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 事件监听,当服务器有新的数据事件发送时,该事件会被触发。
const source = new EventSource('/sse'); source.onmessage = (event) => { console.log(event.data); };
在上述代码中,我们建立了一个 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