Server-Sent Events 在服务器端节省资源的简单方法

阅读时长 4 min read

在 Web 应用中,经常需要实现实时更新页面内容的功能;例如:推送新闻、即时聊天、实时更新数据等等。传统的前端实现是通过 Ajax 轮询获取数据,但会造成服务器的资源浪费,同时用户也会感受到页面的延迟。而 Server-Sent Events(服务器发送事件)是一种轻量级的“推”机制,可以在服务器端节省资源的同时提供实时更新的服务。

什么是 Server-Sent Events

Server-Sent Events 是一种基于 HTTP 协议的即时通讯技术,它建立在简单的事件流协议上,允许 Web 服务器通过单向连接向客户端发送事件或数据。相较于 WebSocket,Server-Sent Events 无需进行握手,更加轻量化,适用于少量数据传输和实时事件通知。

Server-Sent Events 的通信过程如下:

  1. 客户端向服务器端发送 HTTP 请求,要求建立 Server-Sent Events(SSE)连接。
  2. 服务器端向客户端响应 SSE 连接请求,建立 SSE 连接,通过连接随时向客户端发送数据。
  3. 客户端通过事件监听器接收从服务器端发送的数据。

Server-Sent Events 的优势

相较于传统的 Ajax 轮询方式,Server-Sent Events 有以下优势:

  • 减少服务器压力:使用 Server-Sent Events 可以通过单向连接响应客户端请求,省去了无用的响应数据,减少了服务器压力。
  • 实时通知:使用 Server-Sent Events 可以实时向客户端发送数据,不需要等待客户端的请求,客户端可以在数据更新时直接进行页面更新。
  • 更加节约带宽:使用 Server-Sent Events 可以减少废弃的请求,使得服务器只发送必要的数据,减少了带宽的消耗。

Server-Sent Events 的使用

Server-Sent Events 分为服务端和客户端两部分,下面是它们的具体实现方法。

服务器端

在 PHP 中,我们可以通过以下代码来实现 Server-Sent Events:

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

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

其中,header("Content-Type: text/event-stream"); 表示返回数据类型为 Server-Sent Events,header("Cache-Control: no-cache"); 表示不缓存数据。

通过 while 循环,不断获取需要发送的数据,使用 echo 发送数据。每个 SSE 事件都需要一个唯一的事件类型,可以通过 event: 标识符来指定,也可以省略。

客户端

在客户端,我们需要创建一个 EventSource 对象,通过监听其 onmessage 事件来接收服务器发送的数据。以下是 JavaScript 中实现 SSE 的代码示例:

new EventSource('sse.php') 表示创建一个 SSE 连接,通过传入的 URL 与服务器进行通信。

source.addEventListener('message') 则表示监听 SSE 的消息事件,当服务器端向客户端发送数据时,onmessage 事件便会被触发。

Server-Sent Events 的局限性

Server-Sent Events 拥有很多优点,但也存在以下局限性:

  • 浏览器兼容性问题:部分浏览器不支持 SSE 的实现,需要使用 polyfill 进行兼容。
  • 单向数据流:SSE 的通信是单向的,只支持由服务器向客户端发送数据,因此不适用于共享实时双向数据的场景。
  • 连接维持:SSE 需要客户端和服务器维持一个长连接,如果连接断开必须重新建立连接。同时如果服务器应用崩溃或重启,客户端需要重新建立连接。

结语

Server-Sent Events 是一种轻量级、高效的即时通讯技术,能够提供实时更新页面内容的服务,同时还可以节省服务器资源。虽然它存在一些局限性,但在适用场景下,仍然是一种优秀的技术方案。

Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67c69ea7cf1e9924e1eda32c

Feed
back