Skip to content

sse ​

为什么需要 SSE ​

传统的客户端-服务器通信方式(如 AJAX 轮询)效率低下且资源消耗大。SSE(Server-Sent Events)提供了一种服务器向客户端推送实时更新的标准方法,建立单向通道,适用于实时通知、数据更新、股票行情等需要服务器主动推送数据的场景。

基本使用 ​

  1. 客户端代码
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();
};
  1. 服务器代码 (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');
});

使用场景 ​

  1. 实时通知系统
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`);
}
  1. 实时数据更新
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`);
  });
}

注意事项 ​

  1. 最大连接数限制,同一个域名最多只允许 6 个 SSE 连接,大于 6 个会导致连接无法建立,
  2. 自动重连机制
  • SSE 默认包含自动重连机制

  • 可通过 retry 字段自定义重连时间

    retry: 10000\n
    data: 消息内容\n\n
  1. 浏览器连接数限制
  • 每个浏览器对同一域名的 SSE 连接数有限制(通常为 6 个)
  • 长时间连接可能占用服务器资源
  1. 兼容性处理
js
function setupRealtime() {
  if (typeof EventSource !== "undefined") {
    return new EventSource("/events");
  } else {
    // 降级到轮询
    return pollForUpdates();
  }
}

参考资料 ​