Appearance
sse
为什么需要 SSE
传统的客户端-服务器通信方式(如 AJAX 轮询)效率低下且资源消耗大。SSE(Server-Sent Events)提供了一种服务器向客户端推送实时更新的标准方法,建立单向通道,适用于实时通知、数据更新、股票行情等需要服务器主动推送数据的场景。
基本使用
- 客户端代码
js
const eventSource = new EventSource("/events");
eventSource.onmessage = (event) => {
console.log("收到消息:", event.data);
};
eventSource.addEventListener("customEvent", (event) => {
console.log("自定义事件:", event.data);
});
eventSource.onerror = (error) => {
console.error("错误:", error);
eventSource.close();
};- 服务器代码 (Node.js 示例)
js
app.get("/events", (req, res) => {
// 设置 SSE 必要的响应头
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
// 发送消息
res.write("data: Hello SSE\n\n");
// 发送带自定义事件的消息
res.write('event: customEvent\ndata: {"value": 42}\n\n');
});使用场景
- 实时通知系统
js
// 客户端
const notificationSource = new EventSource("/notifications");
notificationSource.onmessage = (event) => {
showNotification(JSON.parse(event.data));
};
// 服务器 (Node.js)
function sendNotification(req, res) {
res.write(`data: ${JSON.stringify({ message: "新消息到达" })}\n\n`);
}- 实时数据更新
js
// 客户端
const dataSource = new EventSource("/data-updates");
dataSource.addEventListener("update", (event) => {
updateChart(JSON.parse(event.data));
});
// 服务器 (Node.js)
function broadcastUpdate(data) {
clients.forEach((client) => {
client.write(`event: update\ndata: ${JSON.stringify(data)}\n\n`);
});
}注意事项
- 最大连接数限制,同一个域名最多只允许 6 个 SSE 连接,大于 6 个会导致连接无法建立,
- 自动重连机制
SSE 默认包含自动重连机制
可通过
retry字段自定义重连时间retry: 10000\n data: 消息内容\n\n
- 浏览器连接数限制
- 每个浏览器对同一域名的 SSE 连接数有限制(通常为 6 个)
- 长时间连接可能占用服务器资源
- 兼容性处理
js
function setupRealtime() {
if (typeof EventSource !== "undefined") {
return new EventSource("/events");
} else {
// 降级到轮询
return pollForUpdates();
}
}