37.讲一下 SSE
什么是 SSE
SSE(Server-Sent Events)是一种服务器推送技术,服务器向客户端推送数据而不需要客户端做任何处理。
SSE 的核心特点
单向通信:仅支持服务器向客户端推送数据(客户端无法反向发送消息)。
基于 HTTP:无需复杂协议,兼容现有 HTTP 基础设施(如身份验证、CORS)。
自动重连:内置断线重连机制,客户端会自动尝试重新连接。
文本协议:默认传输文本数据(如 JSON),也可通过二进制编码传输其他格式。
轻量高效:相比 WebSocket,SSE 实现更简单,适合低频次数据推送场景。
使用场景
实时仪表盘(如股票价格、监控数据)。
新闻/社交媒体动态更新。
长任务进度通知(如文件上传、数据处理进度)。
简单实时聊天(仅需单向推送时)。
SSE 与 WebSocket 的区别
- SSE 是单向通信,只能服务器向客户端推送,WebSocket 是双向通信,允许服务器与客户端进行全双工通信。
- SSE 属于轻量级,使用简单;WebSocket 协议相对复杂。
- SSE 默认支持断线重连,WebSocket 需要自己实现。
- SSE 一般只用来传送文本,二进制数据需要编码后传送,WebSocket 默认支持传送二进制数据。
- SSE 支持自定义发送的消息类型。
特性 | SSE | WebSocket |
---|---|---|
通信方向 | 单向(服务器 → 客户端) | 全双工(双向通信) |
协议 | HTTP(长连接) | 独立的 ws:// 或 wss:// 协议 |
复杂度 | 简单,无需额外库 | 需处理握手、帧协议等 |
二进制支持 | 需通过 Base64 编码 | 原生支持 |
适用场景 | 低频次服务器推送 | 高频次双向交互(如游戏、聊天) |
浏览器兼容性 | 除 IE 外主流支持 | 广泛支持 |
客户端实现(浏览器端)
使用 EventSource API
监听服务器推送:
// 创建 EventSource 连接(指向服务器端点)
const eventSource = new EventSource("/sse-endpoint");
// 监听默认事件(未指定事件类型时触发)
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("收到数据:", data);
};
// 监听自定义事件(如 'status-update')
eventSource.addEventListener("status-update", (event) => {
console.log("状态更新:", event.data);
});
// 处理错误
eventSource.onerror = (error) => {
console.error("SSE 连接异常:", error);
// 可在此处尝试手动重连
};
服务端实现(示例)
以 Node.js(Express)
为例,需设置响应头并持续发送数据流:
app.get("/sse-endpoint", (req, res) => {
// 设置 SSE 响应头
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
// 定期推送数据
let counter = 0;
const intervalId = setInterval(() => {
counter++;
// 发送数据格式:data: { ... }\n\n(注意换行符)
res.write(
`data: ${JSON.stringify({ time: Date.now(), count: counter })}\n\n`
);
// 自定义事件示例
// res.write('event: status-update\ndata: "Processing..."\n\n');
// 终止条件(如 10 次后关闭)
if (counter >= 10) {
clearInterval(intervalId);
res.end(); // 关闭连接
}
}, 1000);
// 客户端断开连接时清理
req.on("close", () => {
clearInterval(intervalId);
res.end();
});
});