html Server-Sent Events
用 HTML Server-Sent Events 实现实时更新:思路、步骤与落地
在网页需要从后端持续推送信息的场景里,比如实时股票行情、聊天消息、天气变化或任务进度,传统的轮询会带来不必要的流量和延迟。用 HTML Server-Sent Events(SSE)来实现后端到浏览器的单向、有序、低延迟推送,是一种更轻量、更可控的选择。
从“被动等待”到“主动推送”的转变
想象你在等公交,不断刷新页面去查是否到站,不仅费时还容易错过信息;用 SSE 就像在公交站开启了一条“到站提醒”的单向通道,后端一到站就立刻把信息发过去,你只需保持连接打开即可。
核心概念与兼容性
SSE 是 HTML5 的一部分,要求服务器支持相应的响应头与协议。建立连接的关键在于:
- 响应头:服务器需返回
Content-Type: text/event-stream,并以\r\n\r\n结尾,确保浏览器识别为 SSE 流。 - 事件格式:使用
event:、data:、id:、retry:等字段来构造消息体,字段值以\r\n分隔。 - 连接保持:SSE 建立的是长连接,只要客户端未主动关闭,服务器可以持续发送更新。
实战:从搭建连接到发送与处理
客端接入
在浏览器端,使用 EventSource 引入事件源:
<EventSource url="/sse-endpoint" onopen="onOpen" onmessage="onMessage" onerror="onError" />
<script>
function onOpen() {
console.log('连接已建立,开始接收事件');
}
function onMessage(event) {
console.log('收到消息:', event.data);
// 这里可以进行数据解析与业务处理
}
function onError(error) {
console.error('发生错误:', error);
// 可以选择重新连接或进行容错处理
}
</script>
服务端实现(示例:Node.js)
const http = require('http');
const https = require('https');
const fs = require('fs');
const server = https.createServer({
key: fs.readFileSync('path/to/your-key.pem'),
cert: fs.readFileSync('path/to/your-cert.pem')
}, (req, res) => {
if (req.url === '/sse-endpoint') {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
// 模拟推送间隔
const interval = setInterval(() => {
res.write(`event: update\ndata: ${Date.now()}\r\n`);
}, 5000);
// 关闭连接时清理
req.on('close', () => {
clearInterval(interval);
res.destroy();
});
req.on('end', () => {
clearInterval(interval);
res.destroy();
});
}
});
server.listen(443, () => {
console.log('SSE 服务已启动,监听 443 端口');
});
关键步骤加粗
- 响应头设置:
Content-Type: text/event-stream是识别 SSE 的关键。 - 消息格式:
event:、data:字段用\r\n分隔,确保浏览器正确解析。 - 连接管理:服务端需处理连接关闭与重连逻辑,避免内存泄漏。
进阶:延迟、重连与幂等
在高延迟或不稳定的网络下,SSE 依然需要考虑:
- 延迟优化:通过在消息里加入时间戳,前端可剔除旧数据,仅保留最近的有效信息。
- 重连策略:在
onerror中使用指数退避,避免短时间频繁重连。 - 幂等处理:当相同事件多次发送时,用
id:字段做去重或只更新状态,而不是完全重载页面内容。
结语
用 SSE 做实时更新,重点在于让服务端按需推送、客户端稳定接收与处理。结合合理的消息格式、连接管理与容错策略,可以显著降低延迟、减少请求量,并提升用户体验。在需要从后端向前端单向推送的场景里,SSE 是一个务实的选择,比轮询更省资源,比长轮询更轻量。
文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。


还没有评论,来说两句吧...