SSE和WebSocket 是什么,AI 场景下如何选择

一、前置基础:AI 实时通信的底层认知

在讲解具体协议前,先明确两个基础认知,理解两类技术的诞生逻辑与适配边界:

  1. AI 场景的两类核心实时需求

    AI 产品的实时通信需求本质分为两类,对应完全不同的技术路线:

  • 单向流式输出:用户发起一次请求后,服务端持续逐段返回生成结果(如 LLM 逐字输出回答),核心诉求是稳定、低感知延迟、兼容现有基础设施
  • 双向实时交互:对话过程中双方随时可以发送消息(如用户打断生成、实时语音对话、状态同步),核心诉求是低延迟、双向自由传输
  1. 长连接通信的两条技术路线

    实现长连接通信有两条完全不同的技术路径,也是 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 协议,核心有五点原因:

  1. 模式天然匹配:LLM 生成本质是「一次请求、持续单向返回」,完美契合 SSE 的服务端推送模型;WebSocket 的双向能力在此场景属于过度设计,徒增复杂度
  2. 工程复杂度极低:SSE 基于标准 HTTP 响应,服务端仅需十几行代码即可实现,调试可直接用 curl 查看数据流;WebSocket 需要处理协议升级、连接池、心跳、重连等逻辑,代码量是 SSE 的 3-10 倍
  3. 基础设施零改造:SSE 完全兼容现有 HTTP 生态,CDN、负载均衡器、企业防火墙、Nginx 均原生支持,仅需关闭代理缓冲即可正常使用;WebSocket 需要额外配置转发规则、超时策略、粘滞会话
  4. 原生体验保障:浏览器内置自动重连与断点续传,网络抖动时用户几乎无感知;WebSocket 需要手动实现指数退避重连、状态恢复逻辑,极易出现 bug
  5. 性能差异可忽略: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 以上的案例。将流式数据与控制指令分通道传输,是混合架构的核心设计准则。

渐进式演进路径

无需一开始就搭建完整混合架构,可按业务阶段逐步升级:

  1. MVP 阶段:纯 SSE 实现流式输出,满足核心对话需求
  2. 增长阶段:新增 WebSocket 通道,支持用户打断、状态同步等双向功能
  3. 成熟阶段:补充 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 响应逻辑 中高,需管理连接、心跳、重连

五、常见认知误区

  1. 误区一:WebSocket 性能更好,应该优先选用

    纠正:WebSocket 仅在传输层延迟上有微弱优势,在 LLM 流式输出场景中,推理耗时是绝对瓶颈,传输差异可忽略。而 SSE 在工程复杂度、兼容性、运维成本上有显著优势,单向场景下 SSE 才是更优解。

  2. 误区二:SSE 是简化版的 WebSocket,能力更弱

    纠正:两者是定位不同的平行技术,而非进阶关系。SSE 原生具备的自动重连、断点续传、HTTP 生态全兼容等特性,是 WebSocket 不具备的。在单向推送场景下,SSE 是更专业、更完善的方案,而非简化版。

  3. 误区三:做 AI 产品就必须上混合架构

    纠正:混合架构是应对复杂双向需求的演进方案,不是起步标配。绝大多数对话类产品在 MVP 和增长阶段,纯 SSE 完全可以满足需求。提前引入 WebSocket 只会徒增开发和运维成本,违背技术选型的极简原则。

  4. 误区四:SSE 只能传文本,完全无法支持多模态

    纠正:SSE 可以通过 Base64 编码传输二进制数据,只是会增加约 33% 的传输开销。对于低频、小体积的多模态内容,SSE 完全可以承载;只有高频、大流量的二进制实时传输场景,才需要切换为 WebSocket。

  5. 误区五:WebSocket 连接数承载能力远不如 SSE

    纠正:单连接内存占用 WebSocket 确实更高,但在合理的资源配置下,两者都能支撑万级以上并发。真正的瓶颈往往是业务逻辑与数据库性能,而非协议本身的连接承载能力。


六、生产落地实操建议

6.1 选型决策参考

遵循「极简优先,按需升级」的原则,按以下路径判断:

  1. 核心需求是 LLM 文本流式输出 → 首选 SSE
  2. 需要低延迟双向控制指令 → 简单场景用 SSE + HTTP POST 控制指令即可
  3. 需要实时语音、高频双向交互 → 引入 WebSocket,采用混合架构
  4. 面向企业级客户 → 必须保留 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 场景下技术选型的最佳准则。

相关推荐
DigitalOcean5 小时前
OpenCode AI编程实践:利用推理路由低成本开发游戏
llm·agent
带刺的坐椅1 天前
从 Claude Code 隐私争议,看 SolonCode 的设计选择
ai·llm·agent·claudecode·soloncode·codingplan
MomentYY1 天前
Temperature:AI 的“脑洞旋钮”
前端·llm·ai编程
Darling噜啦啦1 天前
上下文工程实战:从 Prompt 到 Harness 的三次 AI 工程化浪潮
llm·ai编程
Hyyy2 天前
Function Calling / Tool Use的原理和实现模式
前端·llm·ai编程
智泊AI2 天前
Loop Engineering 为什么会出现?一个 Loop 的组成部分有哪些?
llm
凌奕2 天前
别用文档约束你的 Agent:聊聊 Agent 开发流程的思想
llm·github·agent
Java之美3 天前
vLLM 是怎么工作的?
llm