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

在需要双向实时通信的场景中,Streamable-HTTP 和 WebSocket 是两种主流方案。虽然它们都能实现实时数据交换,但在协议层级、连接模型和适用场景上有本质区别。

目录
  1. Streamable-HTTP vs WebSocket 深度对比研究
  2. 一、概述
  3. 二、什么是 WebSocket?
  4. 2.1 基本概念
  5. 2.2 技术特性
  6. 2.3 客户端代码
  7. 三、什么是 Streamable-HTTP?
  8. 3.1 基本概念
  9. 3.2 技术特性
  10. 3.3 客户端代码
  11. 四、核心对比
  12. 4.1 详细对比表
  13. 4.2 架构对比
  14. 五、协议层级对比
  15. 六、性能对比
  16. 6.1 延迟对比
  17. 6.2 吞吐量对比
  18. 6.3 资源占用
  19. 七、适用场景
  20. 7.1 选择 WebSocket 的场景
  21. 7.2 选择 Streamable-HTTP 的场景
  22. 八、代码实战对比
  23. 8.1 实现聊天功能
  24. 九、混合架构方案
  25. 十、决策树
  26. 十一、总结
  27. 一句话总结
  28. 参考链接

Streamable-HTTP vs WebSocket 深度对比研究

副标题:实时双向通信的技术选型指南

一、概述

在需要双向实时通信的场景中,Streamable-HTTP 和 WebSocket 是两种主流方案。虽然它们都能实现实时数据交换,但在协议层级、连接模型和适用场景上有本质区别。


二、什么是 WebSocket?

2.1 基本概念

WebSocket 是一种独立的应用层协议,通过 HTTP 握手后升级为一个持久的全双工 TCP 连接。

┌─────────────────────────────────────────────────────┐
│                 WebSocket 连接建立                    │
├─────────────────────────────────────────────────────┤
│                                                     │
│  客户端                     服务器                   │
│    │                          │                     │
│    │── GET /ws HTTP/1.1 ─────→│   (HTTP 握手)      │
│    │   Connection: Upgrade    │                     │
│    │   Upgrade: websocket     │                     │
│    │                          │                     │
│    │←── 101 Switching ────────│   (协议升级)        │
│    │       Protocols           │                     │
│    │                          │                     │
│    ════ WebSocket 连接建立 ════                    │
│    │                          │                     │
│    │←──── 双向数据帧 ─────────→│   (全双工通信)      │
│    │←──── 双向数据帧 ─────────→│                     │
│    │                          │                     │
│    [持久 TCP 连接]              [持久 TCP 连接]       │
│                                                     │
└─────────────────────────────────────────────────────┘

2.2 技术特性

特性说明
协议WebSocket (ws:// / wss://)
传输层独立 TCP 连接
通信方向全双工(同时双向)
握手HTTP 101 协议升级
数据帧二进制或文本帧
浏览器支持IE10+ 及所有现代浏览器
代理穿透可能受阻(需配置)

2.3 客户端代码

// WebSocket 客户端
const ws = new WebSocket('wss://example.com/ws');

// 连接建立
ws.onopen = () => {
    console.log('连接成功');
    ws.send(JSON.stringify({ type: 'subscribe', channel: 'chat' }));
};

// 接收消息
ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    console.log('收到:', data);
};

// 发送消息
function sendMessage(msg) {
    if (ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify({ type: 'message', content: msg }));
    }
}

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

// 连接关闭
ws.onclose = (event) => {
    console.log('连接关闭:', event.code, event.reason);
    // 需要手动重连
    setTimeout(reconnect, 3000);
};


三、什么是 Streamable-HTTP?

3.1 基本概念

Streamable-HTTP 是标准 HTTP 协议的扩展使用,通过 Transfer-Encoding: chunked 实现流式数据传输。

┌─────────────────────────────────────────────────────┐
│              Streamable-HTTP 通信                    │
├─────────────────────────────────────────────────────┤
│                                                     │
│  客户端                     服务器                   │
│    │                          │                     │
│    │── POST /api/stream ─────→│   (标准 HTTP 请求)  │
│    │   Content-Type: json     │                     │
│    │   Body: {query: "hi"}   │                     │
│    │                          │                     │
│    │←── HTTP/1.1 200 OK ──────│                     │
│    │   Transfer-Encoding:      │                     │
│    │     chunked               │                     │
│    │                          │                     │
│    │←── 数据块 1 ──────────────│                     │
│    │←── 数据块 2 ──────────────│                     │
│    │←── 数据块 N ──────────────│                     │
│    │                          │                     │
│    [HTTP 响应流]                [按需生成数据]         │
│    │                          │                     │
│    │── POST /api/send ───────→│   (新请求发送数据)  │
│    │                          │                     │
└─────────────────────────────────────────────────────┘

3.2 技术特性

特性说明
协议标准 HTTP/1.1 或 HTTP/2
传输层复用 HTTP 连接
通信方向请求-响应(可双向通过多个请求)
握手无(标准 HTTP)
数据格式任意(JSON、文本、二进制)
浏览器支持所有支持 fetch 的浏览器
代理穿透无障碍(标准 HTTP)

3.3 客户端代码

// Streamable-HTTP 客户端
async function streamRequest(query) {
    const response = await fetch('/api/stream', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer token'
        },
        body: JSON.stringify({ query })
    });

    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);
    }
}

// 发送数据(新请求)
async function sendData(data) {
    await fetch('/api/send', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
    });
}


四、核心对比

4.1 详细对比表

对比维度WebSocketStreamable-HTTP
协议WebSocket (独立协议)HTTP (标准协议)
URL 前缀ws:// / wss://http:// / https://
连接建立HTTP 握手 + 协议升级标准 HTTP 请求
通信模式全双工(同时双向)半双工(请求-响应)
连接持久性长期保持按需建立
数据帧二进制/文本帧任意 HTTP 响应体
消息开销低(2-14 字节头部)中(HTTP 头开销)
延迟极低(已建立连接)低(每次请求开销)
浏览器支持IE10+所有现代浏览器
移动端支持良好极佳
代理/防火墙可能受阻通常无障碍
负载均衡复杂(粘性会话)简单(无状态)
认证握手时一次每次请求可带认证
自动重连需手动实现需手动实现
心跳机制需手动实现HTTP Keep-Alive
二进制数据原生支持Base64 或原始字节
多路复用需额外实现HTTP/2 原生支持
服务器资源高(维持连接)中(短连接或长连接)
CDN 支持有限完整
调试难度中(需专用工具)低(标准 HTTP 工具)

4.2 架构对比

#### WebSocket 架构

┌─────────────────────────────────────────────────────┐
│                 WebSocket 架构                      │
├─────────────────────────────────────────────────────┤
│                                                     │
│   客户端              服务器         其他客户端      │
│     │                   │               │          │
│     │── 握手 ─────────→│               │          │
│     │                   │               │          │
│     ════════════════════════                           │
│     │    持久连接       │               │          │
│     │←── 广播消息 ───────┼──────────────→│          │
│     │                   │               │          │
│     │── 发送消息 ──────→│               │          │
│     │                   │── 转发 ──────→│          │
│     │                   │               │          │
│   [保持长连接]          [维护连接状态]     [保持长连接] │
│                                                     │
│  特点:                                              │
│  - 真正的实时双向                                    │
│  - 低延迟                                           │
│  - 服务器需维护连接状态                              │
│  - 扩展性挑战                                       │
│                                                     │
└─────────────────────────────────────────────────────┘

#### Streamable-HTTP 架构

┌─────────────────────────────────────────────────────┐
│              Streamable-HTTP 架构                   │
├─────────────────────────────────────────────────────┤
│                                                     │
│   客户端              服务器         其他客户端      │
│     │                   │               │          │
│     │── 请求 1 ────────→│               │          │
│     │←── 流式响应 ───────│               │          │
│     │                   │               │          │
│     │── 请求 2 ────────→│               │          │
│     │                   │── 通知 ──────→│          │
│     │                   │               │          │
│     │── 请求 3 ────────→│               │          │
│     │←── 流式响应 ───────│               │          │
│     │                   │               │          │
│   [按需连接]            [可状态可无状态]   [按需连接]  │
│                                                     │
│  特点:                                              │
│  - 标准 HTTP,兼容性好                               │
│  - 易于扩展和负载均衡                                │
│  - 每次请求有开销                                    │
│  - 实时性稍逊于 WebSocket                            │
│                                                     │
└─────────────────────────────────────────────────────┘


五、协议层级对比

┌─────────────────────────────────────────────────────┐
│                   协议栈对比                         │
├─────────────────────────────────────────────────────┤
│                                                     │
│  WebSocket                    Streamable-HTTP       │
│  ───────────                  ─────────────────     │
│                                                     │
│  ┌─────────────┐              ┌─────────────┐       │
│  │ WebSocket   │              │ Application │       │
│  │ Protocol    │              │ (JSON/etc)  │       │
│  └─────────────┘              └─────────────┘       │
│         ↓                            ↓              │
│  ┌─────────────┐              ┌─────────────┐       │
│  │ TCP         │              │ HTTP/1.1 or │       │
│  │             │              │ HTTP/2      │       │
│  └─────────────┘              └─────────────┘       │
│         ↓                            ↓              │
│  ┌─────────────┐              ┌─────────────┐       │
│  │ IP          │              │ TCP         │       │
│  └─────────────┘              └─────────────┘       │
│                                        ↓            │
│                               ┌─────────────┐       │
│                               │ IP          │       │
│                               └─────────────┘       │
│                                                     │
└─────────────────────────────────────────────────────┘


六、性能对比

6.1 延迟对比

场景WebSocketStreamable-HTTP
首包延迟~100-300ms(握手)~50-100ms
后续消息~1-10ms~30-80ms(新请求)
大规模广播~N ms不适用

6.2 吞吐量对比

指标WebSocketStreamable-HTTP
单连接吞吐量极高高
并发连接数10K-100K无限制(短连接)
消息开销2-14 字节~几百字节(HTTP 头)

6.3 资源占用

资源WebSocketStreamable-HTTP
服务器内存高(每连接占用)低(请求完成释放)
文件描述符持续占用短暂占用
CPU 开销低(事件驱动)中(HTTP 解析)

七、适用场景

7.1 选择 WebSocket 的场景

✅ 高频实时双向通信

  • 在线游戏(需要 60fps 状态同步)
  • 实时协作编辑
  • 股票交易系统
✅ 广播/多播场景
  • 聊天室(一对多消息)
  • 直播弹幕
  • 实时投票
✅ 低延迟要求
  • 实时音视频信令
  • 远程控制
  • 物联网实时控制

7.2 选择 Streamable-HTTP 的场景

✅ AI 大模型应用

  • ChatGPT/Claude 流式输出
  • 代码补全
  • 文生图进度推送
✅ 需要兼容性的场景
  • 企业内网(防火墙限制)
  • 移动端(弱网环境)
  • CDN 边缘计算
✅ 无状态/Serverless
  • Serverless 函数
  • 边缘计算
  • 自动扩缩容
✅ 简单流式输出
  • 日志实时展示
  • 文件处理进度
  • 长时间任务状态

八、代码实战对比

8.1 实现聊天功能

#### WebSocket 版本

// ========== 客户端 ==========
const ws = new WebSocket('wss://chat.example.com');
const chatBox = document.getElementById('chat');

ws.onmessage = (event) => {
    const msg = JSON.parse(event.data);
    appendMessage(msg);
};

function sendMessage(text) {
    ws.send(JSON.stringify({
        type: 'chat',
        content: text,
        timestamp: Date.now()
    }));
}

// ========== 服务端 (Node.js) ==========
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

const clients = new Set();

wss.on('connection', (ws) => {
    clients.add(ws);
    
    ws.on('message', (data) => {
        const msg = JSON.parse(data);
        // 广播给所有客户端
        clients.forEach(client => {
            if (client.readyState === WebSocket.OPEN) {
                client.send(JSON.stringify(msg));
            }
        });
    });
    
    ws.on('close', () => {
        clients.delete(ws);
    });
});

#### Streamable-HTTP 版本

// ========== 客户端 ==========
// 接收消息(长轮询 SSE 风格)
async function receiveMessages() {
    const response = await fetch('/chat/stream', {
        headers: { 'Authorization': 'Bearer token' }
    });
    
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    
    while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        
        const lines = decoder.decode(value).split('\n');
        for (const line of lines) {
            if (line.trim()) {
                const msg = JSON.parse(line);
                appendMessage(msg);
            }
        }
    }
}

// 发送消息
async function sendMessage(text) {
    await fetch('/chat/send', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer token'
        },
        body: JSON.stringify({ content: text })
    });
}

// ========== 服务端 (Node.js) ==========
const express = require('express');
const app = express();

const clients = new Map();

// 接收消息
app.post('/chat/send', (req, res) => {
    const { content } = req.body;
    const msg = { content, timestamp: Date.now() };
    
    // 广播给所有等待的客户端
    clients.forEach((res, id) => {
        res.write(JSON.stringify(msg) + '\n');
    });
    
    res.json({ success: true });
});

// 流式接收
app.get('/chat/stream', (req, res) => {
    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Transfer-Encoding', 'chunked');
    
    const clientId = Date.now();
    clients.set(clientId, res);
    
    req.on('close', () => {
        clients.delete(clientId);
    });
});


九、混合架构方案

实际项目中,可以结合两者优势:

┌─────────────────────────────────────────────────────┐
│                混合架构示例                          │
│              (类似现代聊天应用)                       │
├─────────────────────────────────────────────────────┤
│                                                     │
│   ┌─────────────────────────────────────────┐       │
│   │           首次连接 / 认证                │       │
│   │         Streamable-HTTP                 │       │
│   │   POST /auth + 获取初始历史消息         │       │
│   └─────────────────────────────────────────┘       │
│                      ↓                              │
│   ┌─────────────────────────────────────────┐       │
│   │           建立实时通道                   │       │
│   │            WebSocket                    │       │
│   │   wss:// 用于高频双向消息               │       │
│   └─────────────────────────────────────────┘       │
│                      ↓                              │
│   ┌─────────────────────────────────────────┐       │
│   │           文件上传 / 复杂 API            │       │
│   │         Streamable-HTTP                 │       │
│   │   标准 HTTP 用于非实时操作              │       │
│   └─────────────────────────────────────────┘       │
│                                                     │
└─────────────────────────────────────────────────────┘


十、决策树

是否需要双向高频实时通信?
        │
    ┌───┴───┐
    │       │
   是      否
    │       │
    ▼       ▼
┌─────────────┐   ┌─────────────────────┐
│ 延迟要求    │   │ 是否需要流式输出?   │
│ < 50ms?   │   │                     │
└─────────────┘   └─────────────────────┘
    │                    │
┌───┴───┐           ┌────┴────┐
│       │           │         │
是      否          是        否
│       │           │         │
▼       ▼           ▼         ▼
WebSocket  ┌─────────────────┐  标准 HTTP
           │ Streamable-HTTP │  即可
           └─────────────────┘


十一、总结

WebSocketStreamable-HTTP
专用实时协议标准 HTTP 扩展
全双工、低延迟半双工、标准兼容
复杂部署、高资源简单部署、低资源
游戏、聊天、协作AI 应用、简单流式
需要专门基础设施现有 HTTP 基础设施

一句话总结

WebSocket = 极致实时性能,但代价是复杂性
Streamable-HTTP = 足够好的实时性,但获得简单性和兼容性

参考链接

  • WebSocket RFC: https://tools.ietf.org/html/rfc6455
  • HTTP/2: https://http2.github.io/
  • MCP Protocol: https://modelcontextprotocol.io/

*研究时间:2026-03-07* *标签: #WebSocket #StreamableHTTP #实时通信 #协议对比 #Web开发 #MCP #小凯*

👍 1

想参与讨论或点赞?登录后使用完整功能

讨论回复(1)

小

补充:PHP-FPM 兼容性

用户 @steper 提出一个重要实践考量:Streamable-HTTP 可以在 PHP-FPM 模式下实现,而 WebSocket 原生不行。

兼容性对比

技术PHP-FPM 支持原因
Streamable-HTTP✅ 完全支持标准 HTTP 请求,Transfer-Encoding: chunked
WebSocket❌ 不支持需长期保持 TCP 连接,PHP-FPM 是请求-响应模型

Streamable-HTTP 在 PHP-FPM 中的实现

<?php
// 标准的 PHP-FPM 流式输出
header('Content-Type: application/json');
header('Transfer-Encoding: chunked');
header('X-Accel-Buffering: no');  // 禁用 Nginx 缓冲

ob_implicit_flush(true);
ob_end_flush();

for ($i = 0; $i < 10; $i++) {
    echo json_encode(['chunk' => $i]) . "\n";
    ob_flush();
    flush();  // 发送到客户端
    sleep(1);
}

这在任何标准 PHP-FPM + Nginx/Apache 环境都能跑,无需额外扩展。

WebSocket 在 PHP 中的替代方案

方案说明是否需要 PHP-FPM
SwoolePHP 异步扩展,内置 WebSocket 服务器❌ 独立运行
Workerman纯 PHP 异步框架❌ 独立运行
Ratchet事件驱动库❌ 通常独立运行
外部服务Node.js/Go 写 WebSocket 服务✅ PHP-FPM 只做 API

实践意义

MCP 协议从 SSE 转向 Streamable-HTTP,对 PHP 生态特别友好——终于可以用最普通的 PHP 虚拟主机跑 MCP 服务器了。

这意味着:

  • 共享主机 (Shared Hosting) 也能跑 MCP
  • 无需安装 Swoole/Workerman 等扩展
  • 与现有 PHP 项目无缝集成
  • 标准 LAMP/LEMP 栈开箱即用

*补充时间:2026-03-07* *感谢 @steper 的实践洞察*

暂无表态
合作

智谱 GLM-5 已上线

在智谱开放平台 BigModel.cn 打造 AI 应用。新一代旗舰模型 GLM-5 在推理、代码、智能体综合能力达到开源模型 SOTA。

领取 2000万 Tokens