一、前置基础:AI 实时通信的底层认知
在讲解具体协议前,先明确两个基础认知,理解两类技术的诞生逻辑与适配边界:
-
AI 场景的两类核心实时需求
AI 产品的实时通信需求本质分为两类,对应完全不同的技术路线:
- 单向流式输出:用户发起一次请求后,服务端持续逐段返回生成结果(如 LLM 逐字输出回答),核心诉求是稳定、低感知延迟、兼容现有基础设施
- 双向实时交互:对话过程中双方随时可以发送消息(如用户打断生成、实时语音对话、状态同步),核心诉求是低延迟、双向自由传输
-
长连接通信的两条技术路线
实现长连接通信有两条完全不同的技术路径,也是 SSE 与 WebSocket 的本质分界:
- HTTP 生态内延伸:不脱离 HTTP 协议框架,基于标准 HTTP 请求实现长连接推送,天然兼容所有 HTTP 基础设施,代表是 SSE
- 协议升级换栈:通过 HTTP 握手后切换为独立协议,获得更强的双向通信能力,但需要独立的基础设施支持,代表是 WebSocket
二、核心协议原理逐一拆解
2.1 SSE:基于 HTTP 的服务端单向推送
定义
SSE(Server-Sent Events,服务端事件)是基于标准 HTTP 协议的单向长连接推送技术。客户端发起一次普通 HTTP 请求后,服务器保持响应连接不关闭,持续向客户端推送结构化的文本事件数据,是专门为服务端到客户端的单向数据流设计的通信方案。
底层原理
SSE 完全运行在 HTTP 协议之上,核心机制分为三点:
- 连接建立:客户端发起 GET 请求,声明接受
text/event-stream类型的响应;服务端返回对应 Content-Type,保持响应体持续写入,不结束请求 - 数据传输:服务端以事件为单位写入数据,每个事件遵循标准格式,以双换行符分隔,浏览器原生解析事件
- 连接恢复:浏览器内置自动重连机制,网络断开后自动重试,并通过
Last-Event-ID请求头告知服务端最后接收的消息 ID,实现断点续传
标准事件格式仅包含 4 个字段,极简且通用:
| 字段 | 作用 | 示例 |
|---|---|---|
data: |
事件数据主体(必填) | data: {"token": "你好"} |
event: |
自定义事件类型名 | event: message |
id: |
事件唯一标识,用于断点续传 | id: 1024 |
retry: |
客户端自动重连的间隔时间(毫秒) | retry: 3000 |
具象示例
一次标准 SSE 请求与响应的报文结构如下:
http
# 客户端请求
GET /llm/stream HTTP/1.1
Accept: text/event-stream
# 服务端响应
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
data: {"token": "你"}\n\n
data: {"token": "好"}\n\n
data: {"token": ","}\n\n
适用场景
- LLM 大模型文本流式输出、代码生成等单向结果推送场景
- 实时数据看板、系统通知、进度播报等服务端单向推送场景
- 对兼容性、部署成本要求高,希望复用现有 HTTP 基础设施的场景
2.2 WebSocket:协议升级的全双工通信
定义
WebSocket 是一种独立的全双工应用层通信协议。它通过一次 HTTP 握手完成协议升级后,建立持久化的 TCP 连接,客户端与服务端可以在连接上双向、自由地传输文本或二进制数据,帧级传输开销极低。
底层原理
WebSocket 的核心是「协议升级」与「帧传输」:
- 握手阶段:客户端发起带
Upgrade: websocket头的 HTTP 请求,服务端返回101 Switching Protocols响应,完成协议切换,此后脱离 HTTP 协议 - 传输阶段:数据以 WebSocket 帧为单位传输,帧头仅 2-10 字节,开销远小于 HTTP 报文;支持双向同时发送数据,无需等待请求响应
- 连接管理:协议本身不内置重连、心跳机制,所有连接状态管理、异常恢复逻辑都需要开发者手动实现
具象示例
WebSocket 握手阶段的报文结构如下:
http
# 客户端握手请求
GET /ws/chat HTTP/1.1
Host: api.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
# 服务端握手响应
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
握手完成后,后续数据均以 WebSocket 二进制帧传输,不再有 HTTP 报文格式。
适用场景
- 实时语音对话、多模态交互等需要双向二进制传输的场景
- 用户打断生成、实时状态同步等需要低延迟上行控制的场景
- 协同编辑、在线游戏、实时对战等高频率双向交互场景
三、AI 场景下的选型逻辑与架构实践
3.1 为什么 LLM 流式输出首选 SSE
当前 OpenAI、Claude、Gemini、通义千问等所有主流 LLM 厂商的流式输出,均默认采用 SSE 协议,核心有五点原因:
- 模式天然匹配:LLM 生成本质是「一次请求、持续单向返回」,完美契合 SSE 的服务端推送模型;WebSocket 的双向能力在此场景属于过度设计,徒增复杂度
- 工程复杂度极低:SSE 基于标准 HTTP 响应,服务端仅需十几行代码即可实现,调试可直接用 curl 查看数据流;WebSocket 需要处理协议升级、连接池、心跳、重连等逻辑,代码量是 SSE 的 3-10 倍
- 基础设施零改造:SSE 完全兼容现有 HTTP 生态,CDN、负载均衡器、企业防火墙、Nginx 均原生支持,仅需关闭代理缓冲即可正常使用;WebSocket 需要额外配置转发规则、超时策略、粘滞会话
- 原生体验保障:浏览器内置自动重连与断点续传,网络抖动时用户几乎无感知;WebSocket 需要手动实现指数退避重连、状态恢复逻辑,极易出现 bug
- 性能差异可忽略:SSE 单消息延迟约 5-10ms,WebSocket 约 1-3ms,但 LLM 生成单个 token 需要 10ms 以上,推理本身是瓶颈,传输层的毫秒级差异对端到端体验几乎无影响
3.2 哪些场景必须使用 WebSocket
当产品出现明确的双向实时交互需求时,WebSocket 不可替代,典型场景包括:
| 场景 | 核心诉求 | 代表产品 |
|---|---|---|
| 用户打断生成 | 低延迟发送停止指令,中断模型生成 | 高级对话机器人 |
| 实时语音对话 | 音频流双向传输,端到端延迟 < 500ms | OpenAI Realtime API |
| 多模态实时交互 | 同时传输音频、视频、文本流 | Gemini Live API |
| 协同编辑 / 创作 | 高频双向状态同步 | 在线协作文档 AI 功能 |
| Agent 实时控制 | 工具调用状态、执行进度实时回传 | 智能体工作流 |
3.3 生产级实践:三通道混合架构
成熟的 AI 产品最终都会走向分层混合架构,而非单一协议,标准的「三通道架构」分工如下:
plaintext
markdown
┌─────────────────────────────────────────────────────┐
│ API 网关 │
│ (协议识别 / 流量路由 / 认证鉴权) │
└─────────────┬──────────────┬────────────────────────┘
│ │
┌─────────▼──────┐ ┌────▼──────────┐ ┌──────────┐
│ SSE 流式通道 │ │ WebSocket │ │ HTTP │
│ Token 逐字推送 │ │ 控制通道 │ │ 降级通道 │
│ 高频单向文本 │ │ 打断/状态/控制 │ │ 防火墙兜底│
└─────────────────┘ └───────────────┘ └──────────┘
- SSE 通道:专门承载 LLM 生成的 Token 流式推送,大流量、单向、文本为主
- WebSocket 通道:承载双向控制指令,如停止生成、状态同步、工具调用反馈,小流量、低延迟优先
- HTTP 降级通道:当企业防火墙拦截 WebSocket 时,自动降级为 HTTP POST 实现控制指令传输
架构设计的核心原则
禁止将流式数据与控制消息放在同一 WebSocket 连接上。大流量的 Token 数据会造成 TCP 队头阻塞,导致关键控制指令延迟飙升,实际生产中曾出现控制消息延迟从 50ms 升至 2s 以上的案例。将流式数据与控制指令分通道传输,是混合架构的核心设计准则。
渐进式演进路径
无需一开始就搭建完整混合架构,可按业务阶段逐步升级:
- MVP 阶段:纯 SSE 实现流式输出,满足核心对话需求
- 增长阶段:新增 WebSocket 通道,支持用户打断、状态同步等双向功能
- 成熟阶段:补充 HTTP 降级通道,完善企业环境兼容性
四、核心差异横向对比
| 对比维度 | SSE | WebSocket |
|---|---|---|
| 传输方向 | 单向(服务端→客户端) | 全双工(双向自由传输) |
| 协议基础 | 标准 HTTP 协议,无需升级 | HTTP 101 协议升级,独立协议 |
| 自动重连 | ✅ 浏览器原生支持,零代码 | ❌ 需手动实现重连状态机 |
| 消息续传 | ✅ 原生 Last-Event-ID 机制 | ❌ 需自定义实现 |
| 二进制支持 | ❌ 仅文本,需 Base64 编码(+33% 开销) | ✅ 原生支持二进制 |
| 连接建立耗时 | 1 RTT | 2 RTT |
| 单消息延迟 | 5-10ms | 1-3ms |
| 单连接内存占用 | 2-5 KiB | 10-50+ KiB |
| 防火墙穿透性 | ✅ 标准 HTTP 端口,几乎无拦截 | ⚠️ 5%-10% 企业环境会被拦截 |
| CDN / 代理支持 | ✅ 原生支持,关闭缓冲即可 | ❌ 需特殊配置,部分 CDN 不支持 |
| 调试难度 | 低,curl、浏览器控制台可直接查看 | 高,需专用工具解码帧 |
| 工程实现复杂度 | 低,标准 HTTP 响应逻辑 | 中高,需管理连接、心跳、重连 |
五、常见认知误区
-
误区一:WebSocket 性能更好,应该优先选用
纠正:WebSocket 仅在传输层延迟上有微弱优势,在 LLM 流式输出场景中,推理耗时是绝对瓶颈,传输差异可忽略。而 SSE 在工程复杂度、兼容性、运维成本上有显著优势,单向场景下 SSE 才是更优解。
-
误区二:SSE 是简化版的 WebSocket,能力更弱
纠正:两者是定位不同的平行技术,而非进阶关系。SSE 原生具备的自动重连、断点续传、HTTP 生态全兼容等特性,是 WebSocket 不具备的。在单向推送场景下,SSE 是更专业、更完善的方案,而非简化版。
-
误区三:做 AI 产品就必须上混合架构
纠正:混合架构是应对复杂双向需求的演进方案,不是起步标配。绝大多数对话类产品在 MVP 和增长阶段,纯 SSE 完全可以满足需求。提前引入 WebSocket 只会徒增开发和运维成本,违背技术选型的极简原则。
-
误区四:SSE 只能传文本,完全无法支持多模态
纠正:SSE 可以通过 Base64 编码传输二进制数据,只是会增加约 33% 的传输开销。对于低频、小体积的多模态内容,SSE 完全可以承载;只有高频、大流量的二进制实时传输场景,才需要切换为 WebSocket。
-
误区五:WebSocket 连接数承载能力远不如 SSE
纠正:单连接内存占用 WebSocket 确实更高,但在合理的资源配置下,两者都能支撑万级以上并发。真正的瓶颈往往是业务逻辑与数据库性能,而非协议本身的连接承载能力。
六、生产落地实操建议
6.1 选型决策参考
遵循「极简优先,按需升级」的原则,按以下路径判断:
- 核心需求是 LLM 文本流式输出 → 首选 SSE
- 需要低延迟双向控制指令 → 简单场景用 SSE + HTTP POST 控制指令即可
- 需要实时语音、高频双向交互 → 引入 WebSocket,采用混合架构
- 面向企业级客户 → 必须保留 HTTP 降级通道,应对防火墙拦截
6.2 SSE 落地必避坑点
| 常见陷阱 | 后果 | 解决方案 |
|---|---|---|
| Nginx / 代理默认开启缓冲 | 数据被批量缓存,用户看到整段一次性返回 | Nginx 配置proxy_buffering off;,响应头加X-Accel-Buffering: no |
| 长连接被代理超时切断 | 连接意外中断,重连频繁 | 每 25-55 秒发送一次注释心跳:: keepalive\n\n |
| 原生 EventSource 不支持自定义请求头 | 无法携带 Authorization 等认证头 | 使用@microsoft/fetch-event-source等库,或通过 URL 参数传递 Token |
| 未过滤输入中的换行符 | 恶意内容注入额外事件字段,造成解析异常 | 严格过滤数据中的\r、\n字符,规范事件格式 |
6.3 WebSocket 落地必避坑点
| 常见陷阱 | 后果 | 解决方案 |
|---|---|---|
| 无空闲超时与僵尸连接清理 | 连接资源不释放,内存持续泄漏 | 设置空闲超时阈值,配合心跳检测定期清理无效连接 |
| 无完善的重连机制 | 网络抖动后服务中断,用户体验差 | 实现指数退避 + 随机抖动的重连逻辑,设置最大重试次数 |
| 大帧阻塞小消息 | 大数据帧占用通道,控制消息排队延迟 | 大消息分片传输,应用层实现优先级队列 |
| 缺少 Origin 校验 | 存在跨站 WebSocket 劫持风险 | 强制校验 Origin 头,首条消息完成身份认证 |
6.4 核心监控指标
| 监控指标 | 告警阈值 | 说明 |
|---|---|---|
| 单机并发连接数 | 超过容量的 80% | 提前触发扩容 |
| 消息端到端延迟 p99 | >100ms | 排查后端处理或网络瓶颈 |
| 单连接重连频率 | >5 次 / 分钟 | 网络不稳定或服务端异常 |
| 单连接内存占用 | 超过基线 20% | 存在内存泄漏风险 |
| WebSocket 异常关闭码 1006 占比 | >10% | 网络连接质量差 |
核心选型原则
默认优先选择 SSE,除非明确存在双向实时通信需求;WebSocket 是补充能力而非替代方案;成熟产品最终走向「SSE 流式 + WebSocket 控制 + HTTP 降级」的三通道混合架构。工程复杂度对项目成败的影响,远大于协议本身的性能差异,从简单开始,按需演进,是 AI 场景下技术选型的最佳准则。