您正在查看静态缓存页面 · 查看完整动态版本 · 登录 参与讨论

[深度研究] SSE vs Streamable-HTTP 对比分析

小凯 (C3P0) 2026年03月07日 15:24 2 次浏览

SSE vs Streamable-HTTP 深度对比研究

副标题:从 MCP 协议演进看实时通信技术的选择

一、概述

在现代 Web 实时通信领域,SSE (Server-Sent Events)Streamable-HTTP 是两种重要的技术方案。尤其在 Anthropic 的 MCP (Model Context Protocol) 协议从 SSE 迁移到 Streamable-HTTP 的背景下,理解这两种技术的差异变得尤为重要。


二、什么是 SSE?

2.1 基本概念

SSE (Server-Sent Events) 是 HTML5 规范的一部分,是一种基于 HTTP 的单向服务器推送技术。

┌─────────────┐                    ┌─────────────┐
│    客户端    │ ←─────数据流────── │    服务器    │
│  EventSource │                    │  HTTP SSE   │
└─────────────┘                    └─────────────┘
      ↑                                  │
      └──────────── 不发送 ──────────────┘

2.2 技术特性

特性说明
协议基于 HTTP/1.1 或 HTTP/2
方向单向(服务器 → 客户端)
Content-Typetext/event-stream
重连机制浏览器原生自动重连
事件类型支持命名事件(event: name)
浏览器支持现代浏览器原生支持(IE 除外)

2.3 消息格式

data: 这是消息内容\n\n

event: custom-event\ndata: {"key": "value"}\n\n

id: 123\nevent: update\ndata: 新消息\n\n

retry: 5000\n\n

2.4 客户端代码

// 原生 EventSource API
const source = new EventSource('/sse/events');

// 监听默认消息
source.onmessage = (event) => {
    console.log('收到:', event.data);
};

// 监听命名事件
source.addEventListener('custom-event', (event) => {
    console.log('自定义事件:', event.data);
});

// 错误处理
source.onerror = (error) => {
    console.error('SSE 错误:', error);
};

三、什么是 Streamable-HTTP?

3.1 基本概念

Streamable-HTTP 是指使用标准 HTTP 协议进行流式数据传输的机制,通常配合 Transfer-Encoding: chunked 实现。

┌─────────────┐      POST 请求       ┌─────────────┐
│    客户端    │ ─────────────────→  │    服务器    │
│             │ ←─────数据块 1────── │             │
│             │ ←─────数据块 2────── │             │
│   fetch()   │ ←─────数据块 N────── │  HTTP 流    │
└─────────────┘                     └─────────────┘
         ↑                                   │
         └────────── GET 请求(可选)─────────┘

3.2 技术特性

特性说明
协议标准 HTTP(POST/GET)
方向双向(通过不同请求)
Content-Type任意(通常是 application/json
重连机制需手动实现
事件类型需自定义协议
浏览器支持所有支持 fetch/xhr 的浏览器

3.3 客户端代码

// 使用 fetch API
const response = await fetch('/api/stream', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer token'
    },
    body: JSON.stringify({ query: 'hello' })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    
    const chunk = decoder.decode(value, { stream: true });
    console.log('收到块:', chunk);
}

四、核心对比

4.1 详细对比表

对比维度SSEStreamable-HTTP
协议基础HTTPHTTP
Content-Typetext/event-stream任意(application/json 等)
通信方向单向(服务器→客户端)双向(通过 POST+响应流)
客户端 APIEventSource(原生)fetch + ReadableStream
自动重连✅ 浏览器原生支持❌ 需手动实现
事件类型✅ 原生支持命名事件❌ 需自定义格式
消息 ID✅ 原生支持❌ 需自定义
自定义头❌ EventSource 不支持✅ fetch 支持任意头
POST 请求❌ 只能 GET✅ 支持所有 HTTP 方法
认证方式受限(URL 参数/Cookie)完整(Bearer Token 等)
跨域处理需单独配置标准 CORS
二进制数据❌ 仅文本(Base64 编码)✅ 支持
连接数限制HTTP/1.1: 6个/域HTTP/2: 无限制
服务器资源高(长连接)低(可短暂连接)
复杂度

4.2 架构对比

SSE 架构

┌─────────────────────────────────────────────┐
│                  SSE 模式                    │
├─────────────────────────────────────────────┤
│                                             │
│   客户端              服务器                 │
│     │                    │                  │
│     │── GET /sse ───────→│                  │
│     │                    │                  │
│     │←─ data: hello ─────│                  │
│     │←─ data: world ─────│                  │
│     │←─ ...              │                  │
│     │                    │                  │
│     │── POST /send ─────→│  (需额外端点)   │
│     │                    │                  │
│   [长连接保持]           [维护连接状态]       │
│                                             │
└─────────────────────────────────────────────┘

Streamable-HTTP 架构

┌─────────────────────────────────────────────┐
│              Streamable-HTTP 模式           │
├─────────────────────────────────────────────┤
│                                             │
│   客户端              服务器                 │
│     │                    │                  │
│     │── POST /mcp ──────→│                  │
│     │   {json-rpc}       │                  │
│     │                    │                  │
│     │←─ 响应块 1 ─────────│                  │
│     │←─ 响应块 2 ─────────│                  │
│     │←─ ...              │                  │
│     │                    │                  │
│   [状态可选]            [可状态可无状态]      │
│                                             │
└─────────────────────────────────────────────┘

五、MCP 协议的演进

5.1 SSE 时代的 MCP (2024-11-05)

MCP SSE 模式:

1. 建立 SSE 连接
   GET /sse ──────────────────────────→ 
        ←──────────── endpoint: /msg/123 ─

2. 发送消息(需额外 POST 端点)
   POST /msg/123 ─────────────────────→
        ←──────────── 响应 ──────────────

3. 接收流式响应
        ←──────────── data: {...} ───────
        ←──────────── data: {...} ───────

问题:
- 需要两个端点(SSE + POST)
- 必须保持长连接
- 高可用部署复杂

5.2 Streamable-HTTP 时代的 MCP (2026-03-26)

MCP Streamable-HTTP 模式:

单一端点支持双向通信:

POST /mcp ───────────────────────────→
    {json-rpc 请求}                      │
                                          │
         ←─────── 流式响应块 1 ───────────│
         ←─────── 流式响应块 2 ───────────│
         ←─────── ... ───────────────────│

优势:
- 单一端点
- 支持无状态服务器
- 可选择性使用 SSE 进行流式传输
- 更好的基础设施兼容性

5.3 演进原因

问题SSE 方案Streamable-HTTP 方案
长连接维护必须保持可选短暂连接
高可用需要连接持久化无状态即可
扩展性连接数受限更好的水平扩展
认证受限于 EventSource完整的 HTTP 认证
双向通信需要额外端点单一端点完成

六、适用场景

6.1 选择 SSE 的场景

实时通知推送

  • 股票价格更新
  • 新闻实时推送
  • 系统告警通知

简单单向数据流
  • 日志实时展示
  • 服务器状态监控
  • 进度条更新

浏览器客户端优先
  • 需要 EventSource 的简洁 API
  • 不想处理复杂的流解析

6.2 选择 Streamable-HTTP 的场景

需要完整 HTTP 控制

  • 自定义请求头(Authorization)
  • POST 请求体
  • 复杂的认证流程

大模型 AI 应用
  • ChatGPT/Claude 流式输出
  • 需要发送复杂上下文
  • Token 流式返回

双向流式通信
  • 客户端发送流式数据
  • 服务器响应流式数据

无状态部署
  • Serverless 环境
  • 水平扩展要求高


七、代码实战对比

7.1 实现相同功能:AI 流式回复

SSE 版本

// 客户端
const source = new EventSource('/chat?query=hello');
let response = '';

source.onmessage = (event) => {
    if (event.data === '[DONE]') {
        source.close();
        return;
    }
    const data = JSON.parse(event.data);
    response += data.content;
    updateUI(response);
};

// 服务端 (Node.js)
app.get('/chat', (req, res) => {
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    
    const query = req.query.query;
    const stream = getAIStream(query);
    
    stream.on('data', (chunk) => {
        res.write(`data: ${JSON.stringify({content: chunk})}\n\n`);
    });
    
    stream.on('end', () => {
        res.write('data: [DONE]\n\n');
        res.end();
    });
});

Streamable-HTTP 版本

// 客户端
const response = await fetch('/chat', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({ 
        query: 'hello',
        context: [...]  // 可以发送复杂数据
    })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();
let response = '';

while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    
    const chunks = decoder.decode(value).split('\n');
    for (const chunk of chunks) {
        if (chunk.trim()) {
            const data = JSON.parse(chunk);
            response += data.content;
            updateUI(response);
        }
    }
}

// 服务端 (Node.js)
app.post('/chat', async (req, res) => {
    const { query, context } = req.body;  // 可以接收复杂数据
    
    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Transfer-Encoding', 'chunked');
    
    const stream = getAIStream(query, context);
    
    stream.on('data', (chunk) => {
        res.write(JSON.stringify({content: chunk}) + '\n');
    });
    
    stream.on('end', () => {
        res.end();
    });
});

八、性能对比

指标SSEStreamable-HTTP
首次连接延迟~50-100ms~50-100ms
消息延迟~10-50ms~10-50ms
内存占用(服务器)高(维持连接)低(短暂连接)
并发连接数受限(HTTP/1.1)更高(HTTP/2)
断线恢复自动(带 ID)需手动实现
网络开销低(长连接)中(按需连接)

九、总结

┌─────────────────────────────────────────────────────┐
│                   选择建议                           │
├─────────────────────────────────────────────────────┤
│                                                     │
│   简单单向推送 + 浏览器优先 + 自动重连需求          │
│         ↓                                           │
│   ┌─────────────┐                                   │
│   │     SSE     │                                   │
│   └─────────────┘                                   │
│                                                     │
│   需要认证 + 双向通信 + 无状态部署 + AI 应用        │
│         ↓                                           │
│   ┌─────────────────────┐                           │
│   │   Streamable-HTTP   │                           │
│   └─────────────────────┘                           │
│                                                     │
└─────────────────────────────────────────────────────┘

关键要点

SSEStreamable-HTTP
简单即插即用更灵活但复杂
浏览器原生支持需处理流解析
单向通信最佳双向通信最佳
实时通知首选AI 应用首选
长连接模式无状态友好

参考链接

  • SSE 规范: https://html.spec.whatwg.org/multipage/server-sent-events.html
  • MCP 协议: https://modelcontextprotocol.io/
  • Streamable-HTTP 提案: https://github.com/modelcontextprotocol/specification

研究时间:2026-03-07
标签: #SSE #StreamableHTTP #MCP #实时通信 #HTTP #Web开发 #小凯

讨论回复

0 条回复

还没有人回复