Skip to content

HTML SSE

Server-Sent Events (SSE) 允许网页通过 HTTP 连接从服务器接收自动更新。

SSE 允许服务器在建立初始连接后向客户端(网页)推送数据。这不同于传统的轮询方式,后者由客户端重复请求服务器获取更新。

使用 SSE,更新会通过一个长期存在的连接自动从服务器发送。

常见用例:实时通知(社交媒体动态、新闻更新)、实时数据可视化(股票价格、仪表盘)、状态更新(任务进度)、聊天应用(接收消息)。

所有主流现代浏览器,包括 Chrome、Firefox、Safari、Edge 和 Opera,都支持 Server-Sent Events。

Internet Explorer 不支持 SSE。

EventSource JavaScript 对象用于接收 SSE 通知。

<!-- HTML structure -->
<div id="result"></div>
<!-- JavaScript -->
<script>
const resultElement = document.getElementById('result');
if (typeof(EventSource) !== 'undefined') {
// Create a new EventSource object, specifying the URL of the server endpoint
const source = new EventSource('sse_server.php'); // Replace with your server endpoint
// Handle incoming messages (default 'message' event)
source.onmessage = function(event) {
resultElement.innerHTML += `Data received: ${event.data}<br>`;
};
// Optional: Handle the connection opening
source.onopen = function(event) {
resultElement.innerHTML += 'Connection opened.<br>';
};
// Optional: Handle errors
source.onerror = function(event) {
resultElement.innerHTML += 'Error occurred.<br>';
// You might want to close the connection or attempt to reconnect here
// source.close();
};
} else {
resultElement.innerHTML = 'Sorry, your browser does not support Server-Sent Events.';
}
</script>

示例解释:

  • 检查浏览器是否支持 EventSource。
  • 创建一个新的 EventSource 实例,提供将发送事件的服务器脚本的 URL。
  • 监听 onmessage 事件:服务器每次发送没有特定事件名称的消息时都会触发此事件。
  • event.data 属性包含来自服务器的消息载荷 (payload)。
  • (可选)处理 onopen 和 onerror 事件,用于处理连接状态和错误。

服务器需要通过 HTTP 连接以特定格式发送数据。

服务器响应的关键要求:

  • 将 Content-Type 头部设置为 text/event-stream。
  • 设置适当的缓存控制头部(例如 Cache-Control: no-cache),以防止中间代理进行缓冲。
  • 使用 data:, event:, id:, 或 retry: 字段格式化消息,后跟换行符 (\n)。
  • 使用双换行符 (\n\n) 分隔消息。

PHP 代码(例如 sse_server.php):

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // Recommended to prevent buffering
$time = date('r');
echo "data: The server time is: {$time}\n\n"; // Note the double newline
flush(); // Ensure data is sent immediately
// Example of sending multiple events or keeping connection alive
/*
while(true) {
$currentTime = date('r');
echo "data: Current time: {$currentTime}\n\n";
flush();
sleep(5); // Send update every 5 seconds
}
*/
?>

Node.js 代码(概念示例):

const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
setInterval(() => {
const time = new Date().toLocaleTimeString();
res.write(`data: The server time is: ${time}\n\n`);
}, 1000);
// Send an initial message
const time = new Date().toLocaleTimeString();
res.write(`data: The server time is: ${time}\n\n`);
}).listen(3000, () => {
console.log('SSE server running on port 3000');
});

除了默认的 onmessage,你还可以处理其他事件:

事件描述
onopen连接服务器成功时触发。
onmessage从服务器接收到消息(没有特定事件名称)时触发。
onerror发生错误时触发(例如,连接丢失)。
Custom Events如果服务器发送诸如 event: eventName\ndata: ...\n\n 的消息,你可以使用 source.addEventListener('eventName', function(event) { ... }); 监听自定义事件。