在现代Web应用开发中,实时数据推送与双向通信已成为刚需。从轮询(Polling)到长轮询(Long Polling),再到Server-Sent Events(SSE)与WebSocket,技术不断演进。本文将从协议原理、前端API、适用场景及选型角度,对SSE与WebSocket进行简要而深入的对比分析。
一、Server-Sent Events(SSE)
1.1 原理与规范
SSE基于HTTP协议,允许服务器通过一个长连接向客户端持续推送数据。其核心规范定义于HTML Living Standard,客户端使用EventSource接口。
服务器需设置响应头Content-Type: text/event-stream,并按照特定格式发送消息:
data: 消息内容\n\n
支持自定义事件类型、消息ID(用于断线重连后恢复)及自动重连机制。
1.2 前端API示例
const source = new EventSource('/api/stream');
// 监听默认消息
source.onmessage = (event) => {
console.log('收到数据:', event.data);
};
// 监听自定义事件
source.addEventListener('ping', (event) => {
console.log('ping事件:', event.data);
});
source.onerror = (err) => {
console.error('连接异常', err);
};
1.3 服务端简单示意(Node.js + Express)
app.get('/api/stream', (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
let id = 0;
const timer = setInterval(() => {
res.write(`id: ${id}\n`);
res.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`);
id++;
}, 1000);
req.on('close', () => clearInterval(timer));
});
1.4 优缺点
- 优点:基于HTTP,部署简单;自动重连与事件ID恢复;轻量,无需额外协议。
- 缺点:仅支持服务器→客户端单向通信;文本传输(二进制需编码);浏览器连接数限制(HTTP/1.1下同源最多6个,HTTP/2可多路复用)。
二、WebSocket
2.1 原理与规范
WebSocket(RFC 6455)是一个独立的全双工通信协议,通过HTTP Upgrade机制将连接升级为ws或wss(加密)协议。一旦建立,客户端与服务器可以任意时刻互相发送帧(Frame),开销远低于HTTP请求。
2.2 前端API示例
const ws = new WebSocket('wss://example.com/ws');
ws.onopen = () => {
ws.send('客户端上线');
};
ws.onmessage = (event) => {
console.log('收到消息:', event.data);
};
ws.onclose = () => {
console.log('连接关闭,尝试重连...');
// 需自行实现重连逻辑
};
2.3 服务端简单示意(Node.js + ws库)
import { WebSocketServer } from 'ws';
const wss = new WebSocketServer({ port: 8080 });
wss.on('connection', (ws) => {
ws.on('message', (data) => {
ws.send(`回声: ${data}`);
});
});
2.4 优缺点
- 优点:双向实时、低延迟;支持二进制传输;适合高交互场景。
- 缺点:协议较复杂,需专用服务端支持;连接管理(重连、心跳)需自行实现;负载均衡需处理长连接亲和性。
三、技术对比与选型建议
| 维度 | SSE | WebSocket |
|---|---|---|
| 通信方向 | 单向(服务器 → 客户端) | 双向全双工 |
| 协议 | HTTP / HTTPS | ws / wss(独立协议) |
| 自动重连 | 内置支持,带Last-Event-ID | 需手动实现 |
| 数据格式 | UTF-8文本(可自定义事件) | 文本或二进制帧 |
| 浏览器支持 | 除IE外全部支持 | 现代浏览器广泛支持 |
| 实现复杂度 | 低(EventSource) | 中高(需处理心跳、重连等) |
| 典型场景 | 实时通知、股票行情、日志流、AI流式响应 | 在线游戏、聊天室、协同编辑、高频交易 |
选型原则
- 仅需服务器推送:优先选择SSE,开发成本低,且可利用HTTP基础设施(CDN、缓存控制)。
- 双向高频交互:WebSocket是唯一合理选择。
- 混合架构:可使用WebSocket传输核心双向数据,SSE推送辅助通知;或客户端主动请求用普通HTTP,推送用SSE。
四、总结
SSE与WebSocket并非替代关系,而是面向不同通信模型的互补技术。SSE以极简的API和HTTP生态优势,在单向流式场景(如AI对话流、实时仪表盘)中愈发流行;WebSocket则凭借全双工低延迟特性,在复杂交互应用中占据主导。开发者应基于通信方向性、数据量级、运维成本综合权衡,避免过度设计。
正如RFC 6455所言:“WebSocket旨在解决HTTP难以胜任的实时双向通信问题。”而SSE则完美填补了“单向推送但不想引入复杂协议”的空缺。
参考文献:HTML Living Standard — Server-sent events;RFC 6455 — The WebSocket Protocol
