37.讲一下 SSE

书诚小驿2025/03/05前端面经Http

什么是 SSE

SSE(Server-Sent Events)是一种服务器推送技术,服务器向客户端推送数据而不需要客户端做任何处理。

SSE 的核心特点

  • 单向通信:仅支持服务器向客户端推送数据(客户端无法反向发送消息)。

  • 基于 HTTP:无需复杂协议,兼容现有 HTTP 基础设施(如身份验证、CORS)。

  • 自动重连:内置断线重连机制,客户端会自动尝试重新连接。

  • 文本协议:默认传输文本数据(如 JSON),也可通过二进制编码传输其他格式。

  • 轻量高效:相比 WebSocket,SSE 实现更简单,适合低频次数据推送场景。

使用场景

  • 实时仪表盘(如股票价格、监控数据)。

  • 新闻/社交媒体动态更新。

  • 长任务进度通知(如文件上传、数据处理进度)。

  • 简单实时聊天(仅需单向推送时)。

SSE 与 WebSocket 的区别

  • SSE 是单向通信,只能服务器向客户端推送,WebSocket 是双向通信,允许服务器与客户端进行全双工通信。
  • SSE 属于轻量级,使用简单;WebSocket 协议相对复杂。
  • SSE 默认支持断线重连,WebSocket 需要自己实现。
  • SSE 一般只用来传送文本,二进制数据需要编码后传送,WebSocket 默认支持传送二进制数据。
  • SSE 支持自定义发送的消息类型。
特性SSEWebSocket
通信方向单向(服务器 → 客户端)全双工(双向通信)
协议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();
  });
});
最后更新时间' 2025/3/5 20:36:04