Skip to content

HTML5 服务器发送事件 (SSE)

服务器发送事件 (Server-Sent Events, SSE) 是一种 Web 技术,允许服务器在任何时候向客户端推送数据。它基于标准的 HTTP 协议,提供了一种轻量级的、从服务器到客户端的单向通信方式。

这与客户端必须主动请求数据的传统模式(轮询)相反。SSE 非常适合那些需要从服务器获取实时更新的应用场景,例如:

  • 社交网络上的好友状态更新
  • 股票行情数据
  • 新闻网站的实时头条
  • 体育比赛的比分直播

SSE vs. WebSockets

SSE 经常与 WebSockets 进行比较,它们都实现了服务器推送功能,但有关键区别:

  • 通信方向: SSE 是单向的(服务器 -> 客户端)。WebSockets 是双向的。
  • 协议: SSE 基于标准的 HTTP/HTTPS,无需特殊协议或服务器实现。WebSockets 使用自己的 ws://wss:// 协议。
  • 复杂性: SSE 更简单,API 更轻量。如果你的应用只需要从服务器接收更新而不需要向服务器发送大量数据,SSE 是一个更简单的选择。
  • 自动重连: SSE 内置了断线自动重连的机制,而 WebSockets 需要手动实现。

客户端实现:EventSource 对象

在客户端,接收 SSE 非常简单,只需创建一个 EventSource 对象,并为其指定一个能发送事件流的服务器端 URL。

html
<div id="result"></div>

<script>
// 检查浏览器是否支持 EventSource
if(typeof(EventSource) !== "undefined") {
  // 创建一个新的 EventSource 对象,指向服务器端的事件源
  var source = new EventSource("demo_sse.php");

  // 监听 'message' 事件,这是默认的事件类型
  source.onmessage = function(event) {
    document.getElementById("result").innerHTML += event.data + "<br>";
  };

  // 你也可以监听自定义名称的事件
  source.addEventListener('ping', function(event) {
    console.log('Received a ping:', event.data);
  });

  // 监听连接打开
  source.onopen = function() {
    console.log('Connection to server opened.');
  };

  // 监听错误
  source.onerror = function() {
    console.log('EventSource failed.');
  };

} else {
  document.getElementById("result").innerHTML = "抱歉,您的浏览器不支持服务器发送事件...";
}
</script>
  • new EventSource("URL"): 创建实例并连接到服务器。
  • onmessage: 当从服务器收到没有指定事件名的消息时触发。
  • addEventListener('eventName', callback): 监听由服务器指定的特定事件。
  • event.data: 包含了从服务器发送来的消息数据。

服务器端实现

服务器端的实现需要遵循特定的格式。服务器必须发送一个特殊的 Content-Type 头,并且响应体中的每条消息都必须以 data: 开头,并以两个换行符 \n\n 结尾。

PHP 示例 (demo_sse.php):

php
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
?>
  • Content-Type: text/event-stream: 这是 SSE 必需的 MIME 类型。
  • Cache-Control: no-cache: 确保事件流不会被缓存。
  • data: ...\n\n: 这是消息的标准格式。

服务器可以保持连接打开,并根据需要随时向客户端发送新的 data: 块。

本站内容仅供学习和研究使用。