1. SSE 的背景
Server-Sent Events (SSE) 是一种服务器推送技术,允许服务器向客户端实时推送数据。在以下场景特别有用:
- 实时数据更新(如股票价格、天气信息)
- 社交媒体信息流
- 实时日志显示
- 进度通知
2. SSE 的本质
SSE 本质上是基于 HTTP 协议的单向通信机制:
- 使用 HTTP 长连接实现服务器到客户端的单向数据流
- 数据格式为纯文本,编码必须是 UTF-8
- 基于标准 HTTP 协议,无需特殊协议支持
3. SSE 的特点
- 单向通信:服务器到客户端的单向数据流
- 自动重连:断开后默认自动重连
- 简单易用:使用标准 HTTP,无需 WebSocket 的复杂配置
- 支持自定义事件
- 天然支持跨域(CORS)
4. SSE 客户端 API
基本使用示例:
javascript
const evtSource = new EventSource('/events');
// 监听消息
evtSource.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log(data);
};
// 监听连接打开
evtSource.onopen = function() {
console.log('连接已建立');
};
// 监听错误
evtSource.onerror = function(err) {
console.error('发生错误:', err);
};
// 监听自定义事件
evtSource.addEventListener('custom-event', function(e) {
console.log('自定义事件:', e.data);
});
// 关闭连接
// evtSource.close();
5. SSE 服务端实现
数据格式
服务器发送的数据必须遵循特定格式:
- 每条消息以
data:
开头 - 每条消息以
\n\n
结尾 - 支持多个字段:data、event、id、retry
data 字段
kotlin
data: 消息内容\n\n
多行数据:
kotlin
data: 第一行\n
data: 第二行\n\n
id 字段
用于消息标识,断线重连时会发送 Last-Event-ID
头:
makefile
id: 1\n
data: 消息内容\n\n
event 字段
用于指定事件类型:
vbnet
event: custom-event\n
data: 消息内容\n\n
retry 字段
指定重连时间(毫秒):
makefile
retry: 10000\n
data: 消息内容\n\n
6. Node 服务器实例
javascript
const express = require('express');
const app = express();
app.get('/events', (req, res) => {
// 设置 SSE 所需的 headers
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
// 发送初始数据
res.write('data: 连接已建立\n\n');
// 定时发送数据
const intervalId = setInterval(() => {
const data = {
time: new Date().toISOString(),
value: Math.random()
};
res.write(`data: ${JSON.stringify(data)}\n\n`);
}, 1000);
// 监听连接关闭
req.on('close', () => {
clearInterval(intervalId);
});
});
app.listen(3000, () => {
console.log('SSE 服务器运行在 3000 端口');
});
注意事项
- 格式有特定要求:开头为
data:
、结尾为\n\n
- 每个浏览器的并发 SSE 连接数有限制
- 某些代理服务器可能不支持长连接
- 建议实现错误重试机制
- 大规模使用时注意服务器资源管理
总结
SSE 是一个简单但强大的服务器推送方案:
- 相比 WebSocket 更轻量,实现更简单
- 单向通信满足大多数推送场景
- 基于 HTTP 协议,兼容性好
- 自动重连机制提高可靠性
适用场景:
- 实时数据更新
- 消息通知
- 日志流式处理