1. 概述
SSE 和 Streamable HTTP 都与 基于 HTTP 的流式传输 有关,但它们不是同一层面的概念。
SSE:是一种 具体的浏览器/HTTP 推送技术标准 ,全称 Server-Sent Events 。Streamable HTTP:通常指 可流式返回数据的 HTTP 交互方式 ,更偏向一种能力描述或设计模式,而不是像 SSE 那样严格、单一的浏览器标准。
如果放在实际工程语境里,可以这样理解:
SSE是一种"如何流"的 标准方案 。Streamable HTTP是"HTTP 请求/响应可以边生成边返回"的 更宽泛能力 ,其中可以用 SSE,也可以不用 SSE。
2. 什么是 SSE
2.1 定义
SSE 的全称是 Server-Sent Events ,即 服务器向客户端单向持续推送事件 的机制。它基于 HTTP,最常见的响应头是:
服务器建立一个 HTTP 连接后,不立即一次性返回完整响应,而是 持续不断地往连接里写入事件数据 ;客户端一边接收,一边处理。
它最典型的使用方式是在浏览器中通过 EventSource API 订阅服务端事件流。
2.2 工作方式
SSE 的典型流程:
- 客户端向服务端发起一个普通 HTTP 请求。
- 服务端返回
text/event-stream。 - 连接保持打开。
- 服务端按约定格式持续写入事件。
- 客户端收到一条处理一条。
- 若连接断开,浏览器通常会自动重连。
2.3 数据格式
SSE 的消息是 文本协议 ,常见字段包括:
event:事件名data:事件内容id:事件 IDretry:重连等待时间
示例:
注意:
- 每个事件以一个空行结束。
- 一条事件里可以有多行
data:。 - 默认事件类型可不写
event:。
2.4 浏览器端示例
2.5 适用场景
SSE 很适合:
- 实时通知
- 任务进度更新
- 日志流展示
- AI 文本生成逐字/逐段返回
- 股票/监控面板的轻量实时刷新
2.6 优点
- 基于 HTTP,部署和接入成本低
- 浏览器原生支持
EventSource - 自动重连能力较方便
- 服务端到客户端的单向推送足够简单直接
- 文本流天然适合展示增量内容
2.7 局限
- 只能服务端推客户端,不能双向实时通信
- 主要是文本格式,不适合复杂二进制通信
- 某些代理、网关、超时配置可能影响长连接稳定性
- 浏览器端的请求控制能力不如
fetch灵活 - 不适合强交互双向会话场景,那类场景更常用 WebSocket 或 WebRTC
3. 什么是 Streamable HTTP
3.1 定义
Streamable HTTP 不是一个像 SSE 那样明确统一、单一的浏览器 API 名称。它通常表示:
HTTP 响应内容不是一次性整体返回,而是可以边生成边发送,客户端边接收边处理。
也就是说,它强调的是 HTTP 的流式传输能力 。
在不同上下文里,Streamable HTTP 可能指:
- 基于 HTTP chunked transfer 的流式响应
- 基于
fetch+ReadableStream的增量读取 - 用 SSE 作为流格式封装
- 用 NDJSON、纯文本分块、分隔符协议等方式做流式输出
- 某些协议框架里定义的一类"可通过 HTTP 流式承载消息"的传输方式
3.2 核心思想
普通 HTTP 常见模式是:
- 服务端准备好完整结果
- 一次性返回
- 客户端一次性读取
而 Streamable HTTP 是:
- 服务端先返回响应头
- 后续内容分块持续写出
- 客户端按块读取并处理
这类能力在 AI、日志、长任务、推理过程展示中非常常见。
3.3 实现方式
它的底层通常依赖:
- HTTP/1.1 的
Transfer-Encoding: chunked - HTTP/2/HTTP/3 的流式帧传输能力
- 客户端的流读取接口,如
ReadableStream
前端示例:
这里并没有使用 SSE,但它同样是 streamable HTTP response 。
3.4 常见流格式
Streamable HTTP 不限定必须使用哪种消息格式,常见包括:
text/event-stream:也就是 SSEapplication/x-ndjson:每行一个 JSONtext/plain:纯文本增量输出application/json-seq:序列化 JSON 流- 自定义分隔符协议
所以它比 SSE 更宽泛。
3.5 适用场景
- 大模型输出 token 流
- 服务端长任务的分阶段结果回传
- 实时日志/审计流
- 数据导出进度与增量结果展示
- 后端代理上游流式接口并继续往前端透传
3.6 优点
- 保持 HTTP 语义,易接入现有网关、鉴权、观测体系
- 比 WebSocket 更容易融入传统 API 架构
- 不限定消息格式,灵活性更高
- 对 AI 输出、日志、长任务尤其合适
3.7 局限
- 标准化程度不如 SSE/ WebSocket 明确
- 不同实现之间协议格式可能不统一
- 如果需要客户端主动高频回传,仍然不如双向协议自然
- 容易受反向代理缓冲、超时、压缩策略影响
4. SSE 与 Streamable HTTP 的关系
4.1 包含关系
可以把两者关系理解为:
Streamable HTTP是 大类SSE是这个大类下的一种 具体协议形式
即:
也就是:
- 所有 SSE 都属于一种 HTTP 流式传输
- 但并不是所有 Streamable HTTP 都是 SSE
4.2 一个直观类比
可以类比成:
Streamable HTTP像"流式运输"这类总方法SSE像其中一种固定规格的运输箱
你可以用标准运输箱,也可以用别的包装方式;只要是边发边收,都可以叫 streamable。
5. 两者的关键区别
表格
| 对比项 | SSE | Streamable HTTP |
|---|
|-----------------|----------------------|--------------------------------|
| 性质 | 具体标准/协议格式 | 泛化能力/设计方式 |
| 典型 Content-Type | text/event-stream | 不固定 |
| 浏览器支持 | 有 EventSource 原生支持 | 通常用 fetch + ReadableStream |
| 消息格式 | 有固定字段规范 | 可自定义 |
| 通信方向 | 单向:服务端到客户端 | 通常也是服务端流式返回,但表达更宽泛 |
| 适合场景 | 通知、进度、事件流 | AI 输出、日志流、任意增量结果 |
| 标准化程度 | 较高 | 较低,依实现而定 |
| 灵活性 | 中等 | 高 |
6. 为什么 AI 场景里经常同时提到这两个词
在大模型或 Agent 场景中,常常会看到:
- 某个接口支持 streaming
- 返回方式可能是 SSE
- 或者文档中写成 streamable HTTP
原因是:
-
业务需求天然适合流式返回
大模型生成文本是逐步完成的,不必等全部生成后再返回。
-
HTTP 基础设施成熟
企业现有鉴权、网关、限流、日志系统普遍围绕 HTTP 构建。
-
SSE 很适合"服务端不断吐文本"
例如 token-by-token 输出、步骤更新、工具调用状态通知。
-
但有时又不想被 SSE 格式限制
比如希望直接传 NDJSON、自定义 JSON chunk,或者兼容更复杂客户端。
因此很多系统会:
- 对浏览器前端提供 SSE
- 对服务间调用提供自定义 streamable HTTP 格式
- 或者同一接口兼容多种模式
7. 与 WebSocket 的区别
用户在理解 SSE / Streamable HTTP 时,经常会与 WebSocket 混淆。
7.1 SSE / Streamable HTTP
- 基于 HTTP 语义
- 更偏"请求后持续返回结果"
- 服务端向客户端输出最自然
- 易复用现有 HTTP 基础设施
7.2 WebSocket
- 建立后变成真正的双向长连接
- 客户端和服务端都可以随时主动发消息
- 更适合聊天室、协同编辑、在线游戏、低延迟双向交互
7.3 如何选
如果需求是:
- 用户发起一个请求
- 服务端持续返回进度/文本/事件
优先考虑:
- SSE
- 或一般的 Streamable HTTP
如果需求是:
- 双方都要随时发消息
- 高频交互
- 真正的实时双向状态同步
优先考虑:
- WebSocket
8. 实际工程中的注意点
8.1 代理和网关缓冲
很多 Nginx、网关、CDN 默认会缓冲响应,这会让"流式"看起来失效。常见问题是:
- 服务端明明在持续写
- 客户端却最后一次性收到
这通常不是代码逻辑问题,而是链路上的缓冲策略导致。
8.2 超时设置
流式请求往往持续时间更长,需要关注:
- upstream timeout
- idle timeout
- read timeout
- 客户端超时
8.3 心跳机制
长连接流式场景下,经常需要定期发送心跳,避免链路被中间层误判为空闲连接。
在 SSE 中,经常用注释行或空事件实现保活。
8.4 消息边界设计
如果不用 SSE,而是自定义 Streamable HTTP,必须明确:
- 一条消息如何结束
- 客户端如何切包
- 错误如何表达
- 结束标记是什么
否则客户端很难稳定解析。
8.5 重连与幂等
SSE 对自动重连支持更自然;如果是普通 streamable HTTP,自定义协议时需要自行考虑:
- 断线后是否支持续传
- 是否需要 message id
- 重放会不会重复消费
9. 一个简明结论
如果只用一句话概括:
- SSE 是一种标准化的、基于 HTTP 的服务端单向事件流协议。
- Streamable HTTP 是更宽泛的概念,指 HTTP 响应可以被持续分块发送和消费,不限定必须采用 SSE 格式。
两者关系不是并列竞争,而更像:
SSE是一种具体实现Streamable HTTP是更上层的能力描述
10. 选型建议
10.1 适合选 SSE 的情况
- 浏览器前端直接消费
- 需要简单稳定的服务端推送
- 事件/进度/文本流为主
- 不需要复杂双向通信
10.2 适合选一般 Streamable HTTP 的情况
- 希望保留 HTTP 流式能力,但不受 SSE 格式限制
- 客户端并不一定是浏览器
EventSource - 需要传 NDJSON、自定义 JSON chunk 或其他协议
- 主要是 AI 推理、日志、批量结果增量返回
10.3 适合选 WebSocket 的情况
- 强双向实时交互
- 客户端也要频繁主动推送消息
- 会话型实时系统