SEE协议
Server-Sent Events(SEE)是一种基于HTTP协议的轻量级服务器推送技术,其底层实现原理可以概括为以下几个核心要点:
1. 基于HTTP长连接的单向通信
SEE使用标准的HTTP协议实现服务器到客户端的单向数据推送。与传统HTTP请求不同的是,SEE通过保持HTTP连接打开(长连接),允许服务器在有新数据时随时向客户端发送。
工作流程
-
客户端发起请求:
客户端通过创建EventSource
对象向服务器发送HTTP请求,请求头中包含:Accept: text/event-stream
Cache-Control: no-cache表明客户端期望接收事件流格式的数据。
-
服务器响应并保持连接:
服务器返回状态码200 OK
,并设置响应头:Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive然后不关闭连接,而是持续向客户端发送数据。
-
数据推送:
服务器以特定格式(见下文)向客户端发送数据,客户端通过监听事件接收这些数据。
2. 数据格式:Event Stream
服务器发送的数据必须遵循text/event-stream
格式,每行以field: value
形式存在,空行表示消息结束。常见字段包括:
data
: 实际数据内容(必选)。event
: 事件类型(可选,默认为message
)。id
: 事件ID(可选,用于重连时恢复状态)。retry
: 重连超时时间(毫秒,可选)。
示例
data: This is a simple message\n\n
event: notification\n
data: {"title": "New Message", "body": "You have 3 new messages"}\n\n
id: 12345\n
data: Update #12345\n\n
3. 自动重连机制
SEE的一大优势是浏览器会自动处理重连,当连接意外断开时(如网络波动),浏览器会在一段时间后自动尝试重新连接服务器。服务器可通过retry
字段指定重连间隔:
retry: 5000\n
data: Server will be back soon\n\n
4. 客户端实现(JavaScript)
浏览器通过EventSource
接口提供SEE支持:
const eventSource = new EventSource('/api/events');
// 监听默认事件(未指定event字段时)
eventSource.onmessage = (event) => {
console.log('Received:', event.data);
};
// 监听自定义事件
eventSource.addEventListener('notification', (event) => {
const data = JSON.parse(event.data);
console.log('Notification:', data.title);
});
// 错误处理
eventSource.onerror = (error) => {
console.error('EventSource failed:', error);
};
5. 服务器实现示例
以下是Node.js + Express实现SEE服务器的简化示例:
const express = require('express');
const app = express();
app.get('/api/events', (req, res) => {
// 设置响应头
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
// 发送初始数据
res.write('data: Connected!\n\n');
// 定时推送数据(例如每5秒)
const intervalId = setInterval(() => {
const message = `data: Server time is ${new Date().toISOString()}\n\n`;
res.write(message);
}, 5000);
// 客户端断开连接时清理资源
req.on('close', () => {
clearInterval(intervalId);
res.end();
});
});
app.listen(3000, () => console.log('Server running on port 3000'));
6. 与WebSocket的核心差异
特性 | Server-Sent Events | WebSocket |
---|---|---|
协议 | HTTP | 独立的WebSocket协议 |
连接管理 | 由浏览器自动重连 | 需要手动实现重连逻辑 |
数据方向 | 单向(服务器→客户端) | 双向 |
二进制支持 | 仅文本 | 支持文本和二进制 |
复杂度 | 简单(基于HTTP) | 较高(需要处理握手、帧等) |
7. 局限性与适用场景
局限性
- 单向通信:无法实现客户端主动向服务器发送数据。
- 浏览器兼容性:IE不支持,需使用Polyfill。
- 性能:长连接会占用服务器资源,高并发场景需优化。
适用场景
- 实时通知(如邮件提醒、社交媒体更新)。
- 股票行情、体育赛事比分等实时数据推送。
- 新闻更新、博客订阅等内容推送。
总结
SEE通过保持HTTP长连接和特定的数据格式,实现了服务器到客户端的轻量级单向通信,其核心优势在于简单易用、自动重连,适合不需要双向通信的实时推送场景。