好的,阿杰,我来给你整理一份 SSE(Server-Sent Events)技术详解,重点讲它原理、HTTP 实现方式、与其他推送技术对比,以及实际应用示例。


SSE 技术详解:使用 HTTP 做服务端数据推送

一、概述

SSE(Server-Sent Events) 是一种基于 HTTP 的单向推送技术,允许服务器主动向客户端发送实时更新数据。

  • 特点:
    • 单向:服务器 → 浏览器
    • 持久连接:使用 HTTP 持久连接(Keep-Alive)
    • 数据格式简单:基于文本(text/event-stream)
    • 自动重连:浏览器端自动处理网络断开

二、SSE 工作原理

  1. 客户端发起请求
    • 浏览器通过 EventSource 对象向服务器发送 HTTP GET 请求
    • 请求头包含: Accept: text/event-stream Cache-Control: no-cache
  2. 服务器保持连接
    • 服务器返回响应: HTTP/1.1 200 OK Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive
    • 持续向客户端发送数据,格式如下: data: 这里是要推送的数据\n\n
    • 每条消息以 两个换行符 \n\n 结束
  3. 客户端接收事件
    • 使用 JS EventSource 对象监听消息: const evtSource = new EventSource("/sse"); evtSource.onmessage = function(event) { console.log(event.data); };
  4. 自动重连
    • 默认断线后浏览器会每隔 3 秒重新连接,可通过 retry 设置: retry: 5000

三、SSE 消息格式

SSE 消息支持几种字段:

字段说明
data:消息正文,可多行
id:消息 ID,用于客户端记录最后接收的事件
event:自定义事件名称,客户端通过 addEventListener 监听
retry:设置客户端重连时间(毫秒)

示例:

id: 1
event: update
data: {"msg":"Hello SSE"}
retry: 5000


注意:每条消息以 空行 结尾


四、SSE 与其他实时技术对比

技术双向通信长连接协议特点
SSEHTTP单向,易用,自动重连,浏览器支持好
WebSocketWS双向,低延迟,复杂
Long PollingHTTP轮询模拟推送,性能低
HTTP/2 PushHTTP2推送静态资源,灵活性有限

SSE 适合

  • 服务器主动推送实时日志、股票行情、社交消息等
  • 客户端只需要接收数据,无需频繁发送请求

五、SSE 服务端实现示例

1. Node.js + Express

const express = require("express");
const app = express();

app.get("/sse", (req, res) => {
    res.setHeader("Content-Type", "text/event-stream");
    res.setHeader("Cache-Control", "no-cache");
    res.setHeader("Connection", "keep-alive");

    let id = 0;
    const interval = setInterval(() => {
        id++;
        res.write(`id: ${id}\n`);
        res.write(`data: {"time": "${new Date().toISOString()}"}\n\n`);
    }, 1000);

    req.on("close", () => {
        clearInterval(interval);
    });
});

app.listen(3000, () => console.log("SSE server running on port 3000"));

2. 客户端

const evtSource = new EventSource("http://localhost:3000/sse");
evtSource.onmessage = function(event) {
    console.log("Received:", event.data);
};


六、SSE 优缺点

优点

  1. 基于标准 HTTP/1.1,无需额外协议
  2. 浏览器原生支持,易用
  3. 自动重连机制
  4. 消息有 ID,方便恢复断线后继续接收

缺点

  1. 单向通信,客户端无法直接通过 SSE 发送消息
  2. HTTP/1.1 长连接限制,大量连接会占用服务器资源
  3. 对老旧浏览器支持有限(IE 除外)

七、优化建议

  1. 使用 Nginx 或代理 支持 SSE: proxy_buffering off; proxy_cache off;
  2. 避免长时间空闲,可发送心跳: data: \n\n
  3. 对大量用户,可考虑 WebSocket 或消息队列 结合 SSE 分发
  4. 设置 retry 优化客户端重连策略