html Server-Sent Events

2026-04-24 09:00:12 454阅读 0评论

用 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零点博客原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
验证码
评论列表 (暂无评论,454人围观)

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

目录[+]