摘要:随着 AI 大模型应用的爆发,传统的 Server-Sent Events (SSE) 协议逐渐暴露出其局限性。2025年,Anthropic 在 MCP 协议中引入的 Streamable HTTP,正在重新定义实时通信的标准。本文将从发展历史、核心痛点、解决方案与技术原理三个维度,深度解析这场协议演进背后的技术逻辑。
一、发展历史:从 Web 标准化到 AI 原生
1.1 SSE 的诞生:HTML5 时代的推送方案
Server-Sent Events (SSE) 并非某家公司的独立发明,而是 W3C 万维网联盟在 HTML5 标准化进程中的产物:
- 2009-2012年:作为 HTML5 规范草案被提出,旨在解决早期 AJAX 轮询的性能瓶颈
- 2012年 :正式成为 W3C 推荐标准,定义了
EventSourceAPI - 设计目标:为浏览器提供一种轻量级的、基于 HTTP 的服务器单向推送机制
SSE 的出现,让网页能够实时接收股票行情、新闻推送、社交媒体更新等,成为 Web 实时化的重要基石。
1.2 Streamable HTTP 的崛起:MCP 协议的架构升级
Streamable HTTP 则是 AI 时代的产物 ,由 Anthropic 为其 Model Context Protocol (MCP) 专门设计:
| 时间节点 | 里程碑事件 |
|---|---|
| 2024年11月 | Anthropic 开源 MCP 协议,初始版本采用 HTTP + SSE 作为远程传输方案 |
| 2025年3月 | MCP 通过 PR #206 正式引入 Streamable HTTP,取代 HTTP+SSE 成为推荐传输机制 |
| 2025年11月 | MCP 规范 2025-11-25 版本进一步巩固 Streamable HTTP 地位,并引入 OAuth 2.1 授权 |
从时间线可以看出,Streamable HTTP 并非要颠覆 SSE 作为通用 Web 标准,而是 针对 AI 大模型场景的特殊需求做出的架构演进。
二、核心痛点:SSE 在 AI 时代的三大局限
2.1 连接管理困境
SSE 基于长连接机制,在 AI 应用中暴露出严重问题:
javascript
// SSE 的典型痛点:连接不稳定
const eventSource = new EventSource('/ai-stream');
eventSource.onerror = (error) => {
// 网络抖动、代理超时、负载均衡切换都会导致断开
console.log('连接断开,需要手动重连...');
// 复杂的重连逻辑、状态恢复、消息去重...
};
- 浏览器并发限制:同一域名下最多 6 个 SSE 连接,多标签页场景下极易耗尽
- 代理与防火墙:长连接常被企业级防火墙、CDN 视为异常而切断
- Serverless 不友好:函数计算平台(如 AWS Lambda)不适合保持长连接
2.2 双向通信的"跛脚"设计
SSE 是严格的单向通道 (服务器→客户端),但 AI 场景需要全双工通信:
用户提问 → AI 思考 → 调用工具 → 返回结果 → 继续生成
↑ ↑ ↑ ↑
客户端 客户端 服务器 服务器
发送 接收 执行 推送
在 SSE 方案中,客户端发送数据必须另开 HTTP 请求,导致:
- 架构复杂:需要维护两条通道(SSE 接收 + HTTP 发送)
- 时序混乱:请求与响应难以精确关联
- 状态分散:上下文需要在多个连接间同步
2.3 云原生架构的适配难题
| 特性 | SSE 表现 | 云原生需求 |
|---|---|---|
| 无状态性 | ❌ 必须保持连接状态 | ✅ 每个请求独立处理,便于水平扩展 |
| 负载均衡 | ❌ 会话粘性强 | ✅ 任意节点可处理任意请求 |
| 容错恢复 | ❌ 断线后难以恢复上下文 | ✅ 通过会话 ID 快速恢复 |
| CDN 支持 | ❌ 边缘节点难以缓存长连接 | ✅ 标准 HTTP 请求,边缘友好 |
三、解决方案:Streamable HTTP 的技术原理
Streamable HTTP 并非创造新协议,而是对 HTTP 已有能力的现代化封装,通过三大机制解决上述痛点。
3.1 核心机制:分块传输编码 (Chunked Transfer Encoding)
Streamable HTTP 利用 HTTP/1.1 原生支持的 Chunked Transfer-Encoding,实现"请求即流、响应即流":
http
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Mcp-Session-Id: 550e8400-e29b-41d4-a716-446655440000
7f
{"jsonrpc":"2.0","result":{"content":"你好"}}
9d
{"jsonrpc":"2.0","result":{"content":"这是"}}
a2
{"jsonrpc":"2.0","result":{"content":"实时推送的消息"}}
0 ← 结束标记
关键特性:
- 即时性:数据一生成立即发送,无需等待完整响应
- 双向性 :请求体同样支持流式上传(
ReadableStream) - 兼容性:所有现代 HTTP 客户端/服务器均支持
3.2 浏览器端的实时接收
通过 Fetch API + ReadableStream,浏览器可以逐块读取服务器推送:
javascript
// Streamable HTTP 的浏览器实现
const response = await fetch('/mcp-endpoint', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Mcp-Session-Id': sessionId // 会话恢复
},
body: JSON.stringify(request),
duplex: 'half' // 允许流式请求体
});
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
// 实时解码并更新 UI
const chunk = new TextDecoder().decode(value);
const message = JSON.parse(chunk);
updateUI(message); // 即时渲染,无需等待全部数据
}
对比 SSE 的 EventSource,Fetch API 提供了更细粒度的流控制:
- 支持 取消请求 (
AbortController) - 支持 读取进度监控
- 支持 自定义请求头 (SSE 的
EventSource无法自定义 headers)
3.3 会话管理:无状态架构的"状态恢复"方案
Streamable HTTP 通过 会话 ID 机制 解决无状态与上下文保持的矛盾:
javascript
// 首次请求:建立会话
const initResponse = await fetch('/mcp', {
method: 'POST',
body: JSON.stringify({ method: 'initialize' })
});
const sessionId = initResponse.headers.get('Mcp-Session-Id');
// 后续请求:携带会话 ID,任意节点可恢复上下文
const streamResponse = await fetch('/mcp', {
method: 'POST',
headers: { 'Mcp-Session-Id': sessionId },
body: JSON.stringify({ method: 'tools/call', ... })
});
// 即使连接到不同服务器节点,也能继续之前的对话
架构优势:
- 水平扩展:无需会话粘性(Session Affinity),任意节点可处理
- 故障转移:连接断开后,新请求自动路由到健康节点
- Serverless 友好:函数实例无需保持长连接,每次调用独立处理
3.4 双向流式的完整实现
MCP 的 Streamable HTTP 支持 两种模式 覆盖所有场景:
| 模式 | HTTP 方法 | 适用场景 | 数据流向 |
|---|---|---|---|
| 流式请求-响应 | POST |
客户端需要发送数据 | 客户端流式上传 → 服务器流式返回 |
| 纯读取流 | GET |
仅接收服务器推送 | 服务器单向流式推送(类似 SSE) |
javascript
// 场景 1:AI 对话(双向流式)
const chatResponse = await fetch('/mcp', {
method: 'POST',
body: createStreamableBody(userInput) // 流式上传
});
// 同时接收流式响应
// 场景 2:订阅通知(单向读取)
const notifyStream = await fetch('/mcp?session_id=xxx', {
method: 'GET'
});
// 持续读取服务器推送
四、总结:协议演进的本质
从 SSE 到 Streamable HTTP,不是技术的颠覆,而是场景驱动下的架构回归:
| 维度 | SSE (2012) | Streamable HTTP (2025) |
|---|---|---|
| 设计目标 | 浏览器实时推送 | AI 大模型双向流式通信 |
| 架构哲学 | 长连接、有状态 | 无状态、可扩展 |
| 云原生适配 | 弱 | 强 |
| 浏览器 API | EventSource |
fetch() + ReadableStream |
| 协议归属 | 通用 Web 标准 | MCP 专用传输层 |
Streamable HTTP 的核心洞察:
不需要为实时通信发明新协议,只需要充分利用 HTTP 的流式能力,并用现代 API 封装成适合 AI 交互的模式。
对于开发者而言,这意味着:
- ✅ 无需学习 WebSocket 的复杂性
- ✅ 享受 HTTP 生态的成熟工具链(CDN、WAF、监控)
- ✅ 天然支持 Serverless 和微服务架构
SSE 并未消亡,在简单的服务器推送场景(如股票行情、日志推送)中依然简洁高效。但在 AI 大模型时代,Streamable HTTP 正在成为实时通信的新范式。
参考链接:
- MCP 协议规范:https://modelcontextprotocol.io
- W3C SSE 标准:https://www.w3.org/TR/eventsource/
- Fetch API Streams 标准:https://streams.spec.whatwg.org/
本文首发于 CSDN,转载请注明出处。