工作原理
客户端用 Accept: text/event-stream 发起普通 HTTP 请求。服务器以该内容类型响应并保持响应体打开,持续写入以空行分隔的 UTF-8 消息。每条消息可包含 event、id、retry 和 data 字段,浏览器解析后向页面派发事件。
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
id: 1041
event: price
data: {"symbol":"ETH","usd":3120.44}
连接断开后,EventSource 会按 retry 间隔自动重连,并携带 Last-Event-ID: 1041,服务器可据此补发遗漏事件。代理不得缓冲响应,通常需要关闭压缩或逐事件刷新。
何时使用与取舍
SSE 适合单向、文本友好的流:实时仪表盘、通知、构建日志、大模型逐字输出和进度提示。它比 WebSocket 简单,因为使用普通 HTTP、支持 Cookie 和标准认证,而且无需自写重连逻辑。当客户端还要频繁发送消息或交换二进制数据时,它并不合适。
每个打开的流都会占用连接和服务端资源。HTTP/1.1 下浏览器限制同域连接数,多标签页可能挤占其他请求;HTTP/2 基本消除了这一限制。慢客户端会积压消息,服务器需要有限队列,以及丢弃或断开落后客户端的策略。只有保存事件 id 和保留窗口时,补发才有效。
常见误解
一个常见误解是 SSE 可以替代 WebSocket。聊天这类需要持续双向输入的场景仍应使用 WebSocket;只读的行情推送用 SSE 代码量小得多。相关概念:长轮询、背压、Webhook。