一、SSE 基本概念
Server-Sent Events (SSE) 是一种允许服务器向客户端(通常是浏览器)推送实时更新的Web技术。它基于HTTP协议,提供了一种简单高效的服务器到客户端的单向通信机制。
主要特点:
-
单向通信:仅服务器→客户端方向
-
基于HTTP:无需特殊协议
-
文本数据:支持UTF-8文本格式
-
自动重连:内置连接恢复机制
-
轻量级:比WebSocket更简单
二、SSE 工作原理
1. 建立连接
客户端通过EventSource API发起连接:
const eventSource = new EventSource('/sse-endpoint');
2. 服务器响应
服务器返回特定格式的流响应:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
data: 这是一条消息\n\n
3. 数据传输格式
SSE使用简单文本协议,每条消息由字段组成,以\n\n
结束:
event: notification
id: 123
data: {"time": "2023-01-01", "message": "Hello"}
retry: 5000\n\n
三、SSE 与 WebSocket 对比
特性 | SSE | WebSocket |
---|---|---|
方向 | 单向(服务器→客户端) | 双向 |
协议 | HTTP | 独立协议(ws://) |
数据格式 | 文本 | 文本/二进制 |
自动重连 | 支持 | 需手动实现 |
浏览器支持 | 除IE外主流浏览器 | 所有现代浏览器 |
复杂度 | 低 | 中高 |
适用场景 | 实时通知、日志流 | 聊天、游戏等交互应用 |
四、SSE 实现示例
客户端实现
// 创建SSE连接
const eventSource = new EventSource('/sse');
// 监听消息
eventSource.onmessage = (e) => {
console.log('收到消息:', e.data);
};
// 监听自定义事件
eventSource.addEventListener('status', (e) => {
console.log('状态更新:', JSON.parse(e.data));
});
// 错误处理
eventSource.onerror = () => {
console.error('连接错误');
// 自动重连
};
服务器实现(Node.js)
const http = require('http');
http.createServer((req, res) => {
if (req.url === '/sse') {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
// 发送初始消息
res.write('data: 连接已建立\n\n');
// 定时推送
let counter = 0;
const timer = setInterval(() => {
counter++;
res.write(`data: 这是第${counter}条消息\n\n`);
// 发送自定义事件
if (counter % 5 === 0) {
res.write('event: alert\ndata: 重要通知!\n\n');
}
}, 1000);
// 连接关闭时清理
req.on('close', () => {
clearInterval(timer);
});
} else {
res.writeHead(404);
res.end();
}
}).listen(3000);
五、SSE 高级特性
1. 消息字段
-
data:消息内容(可多行)
-
id:事件ID(用于重连时Last-Event-ID头部)
-
event:自定义事件类型
-
retry:重连时间(毫秒)
2. 多行数据
data: 第一行\n
data: 第二行\n
data: 第三行\n\n
客户端接收:"第一行\n第二行\n第三行"
3. 自定义事件
event: userupdate\n
data: {"id": 123, "name": "张三"}\n\n
客户端监听:eventSource.addEventListener('userupdate', handler)
六、SSE 使用场景
-
实时通知:社交网络更新、新邮件提醒
-
实时数据监控:股票价格、IoT设备状态
-
日志流:实时显示服务器日志
-
新闻/体育赛事:实时比分更新
-
进度报告:长时间操作进度更新
七、SSE 最佳实践
-
连接管理:
// 安全关闭连接 function closeSSE() { eventSource.close(); }
-
错误处理增强:
eventSource.onerror = (e) => { if (e.eventPhase === EventSource.CLOSED) { console.log('连接被服务器关闭'); } else { console.log('连接出错:', e); } };
-
性能优化:
-
合并多条消息减少HTTP开销
-
适当设置
retry
时间(默认3秒)
-
-
安全考虑:
// 携带认证信息 const eventSource = new EventSource('/sse', { withCredentials: true });
SSE提供了一种简单高效的服务器推送解决方案,特别适合需要服务器主动推送但不需要双向通信的场景。相比轮询和长轮询,SSE更加高效且易于实现。