☰
为什么 AI 对话普遍用 SSE,而不是 WebSocket?
2026/10/8 6:58:58 网站建设 项目流程

1. 核心回答

AI 对话通常是客户端发一次请求,服务端持续把模型生成的结果流回来,所以 SSE 更贴合这个通信模型,而且基于 HTTP,接入和维护成本也比较低。

这句话先说到这里。不要一上来就讲:

SSE 单向、WebSocket 双向、SSE 自动重连……

这些属于面试官继续追问后的展开。


2. AI 对话到底是什么通信模型?

先看最典型的文本对话:

用户输入问题 │ ▼ 客户端 ─────── 请求 ───────► AI 服务 │ ▼ 调用模型 │ 持续生成 Token │ ┌────────────────┼──────────────┐ ▼ ▼ ▼ Token Token Token │ │ │ └────────────────┼──────────────┘ ▼ 客户端 ◄──────── 持续返回生成结果 ────────

核心就是:

客户端主要负责发起请求,服务端负责持续把生成结果推回来。

例如:

客户端:帮我解释一下 React Fiber ↓ 服务端:React ↓ 服务端:React Fiber ↓ 服务端:React Fiber 本质上…… ↓ 服务端:……

客户端并不需要在生成过程中不断向服务端发送消息。所以它非常接近:

一次请求 ↓ 持续响应

这就是 SSE 非常适合的通信模型。


3. 为什么 AI 对话特别适合 SSE?

这里可以明确记住三个原因。

第一:通信模型匹配

SSE 的核心就是:

客户端 ───── HTTP 请求 ─────► 服务端 客户端 ◄════ 持续事件流 ════ 服务端

也就是:

客户端发起请求,服务端持续向客户端推送数据。

而 AI 文本对话恰好就是这个模型。


第二:SSE 基于 HTTP,接入成本低

SSE 本身就是 HTTP 响应流。典型请求:

GET /api/chat/stream Accept: text/event-stream

服务端保持响应连接,然后不断返回:

data: {"content":"你"} data: {"content":"好"} data: {"content":","} data: {"content":"世界"}

所以现有 HTTP 基础设施基本都可以继续使用:

浏览器 ↓ CDN / 反向代理 ↓ 负载均衡 ↓ Nginx ↓ 应用服务器

WebSocket 则需要通过 HTTP Upgrade 完成握手,之后切换成 WebSocket 协议进行双向通信。所以不是:

WebSocket 不能走 HTTP。

而是:

WebSocket 借助 HTTP Upgrade 建立连接,握手完成后就进入 WebSocket 的双向通信阶段。


第三:AI 本身就是流式文本输出

这是 AI 场景非常重要的一点。模型不是一定要等整个答案生成完才返回。可以:

生成一个 Token ↓ 马上发送 ↓ 前端马上渲染 再生成一个 Token ↓ 马上发送 ↓ 前端继续渲染

所以用户看到的是:

React Fiber 本质上是... ↓ React Fiber 本质上是一种... ↓ React Fiber 本质上是一种可中断...

而 SSE 天然就是:

服务端持续发送文本事件。

所以和 AI 的流式输出非常契合。


4. SSE 和 WebSocket 到底有什么区别?

最核心就看通信模型:

SSE: Client ───────────────► Server HTTP Request Client ◄═══════════════ Server Event Stream

而 WebSocket:

Client ◄═══════════════► Server 双向通信

所以:

SSEWebSocket
核心方向服务端 → 客户端双向
建立连接HTTPHTTP Upgrade
后续通信HTTP 响应流WebSocket 帧
文本流很适合适合
二进制不适合很适合
客户端持续发送不适合适合
浏览器原生自动重连EventSource支持需要自行实现
双向高频通信不适合适合

但要注意:

SSE 不是“客户端不能发请求”。

客户端当然可以:

POST /api/chat

向服务端发送消息。只是:

SSE 本身只定义服务端到客户端的事件流,不提供一个同时存在的客户端到服务端消息通道。

因此实际 AI 应用完全可以:

POST /api/chat ↓ 提交用户问题 GET /api/chat/stream ↓ SSE 接收模型输出

或者根据具体设计把请求和流式响应组合成一次 HTTP 交互。


5. WebSocket 能不能做 AI 对话?

当然可以。

Client ◄════════ WebSocket ════════► AI Server

然后:

Client → 用户问题 Server → Token 1 Server → Token 2 Server → Token 3 Server → Token 4

技术上没有问题。所以真正正确的说法不是:

AI 对话不能用 WebSocket。

而是:

对于以服务端流式输出为主的 AI 文本对话,WebSocket 提供的双向能力很多时候用不上,因此 SSE 往往更简单。

这才是技术选型。


6. SSE 的自动重连到底怎么回事?

浏览器原生:

constsource=newEventSource('/api/chat/stream');source.onmessage=(event)=>{console.log(event.data);};

连接断开之后,EventSource会按照 SSE 的规则尝试重新连接。

服务端还可以返回:

retry: 3000

告诉客户端重连等待时间。SSE 还有一个很重要的东西:

id: 101 data: hello

如果连接断开,浏览器重新连接时可以带上:

Last-Event-ID: 101

服务端就可以根据这个 ID 判断:

客户端最后收到的是 101 那么可以从 102 开始继续

但是这里一定要说准确:

SSE 提供了自动重连和 Last-Event-ID 这样的能力,但不等于自动保证业务消息不丢。

真正的断线恢复还需要服务端保存事件、判断从哪里恢复以及处理重复消息。


7. WebSocket 为什么通常需要自己做重连?

WebSocket:

constws=newWebSocket(url);ws.onopen=()=>{};ws.onmessage=()=>{};ws.onclose=()=>{};ws.onerror=()=>{};

连接断了之后:

onclose ↓ 自己决定是否重连 ↓ 等待 ↓ 重新连接 ↓ 重新鉴权 ↓ 恢复订阅 ↓ 处理未确认消息

线上一般还会进一步做:

断线检测 ↓ 指数退避 ↓ 最大重试次数 ↓ 重新鉴权 ↓ 恢复订阅 ↓ 消息恢复 / 重放

如果业务对可靠性有要求,还可能需要:

messageId ACK sequence 重放 幂等

所以区别不是:

WebSocket 没有重连。

而是:

WebSocket 不像 EventSource 那样直接提供浏览器级的自动重连体验,业务需要自己设计连接恢复方案。


8. 那 SSE 一定比 WebSocket 省服务器资源吗?

不能这么说。实际资源消耗取决于:

连接数量 消息频率 消息大小 连接持续时间 服务端实现 代理层 心跳频率 发送缓冲 业务状态

例如:

100 万长连接

无论 SSE 还是 WebSocket,都不是“没有成本”。都需要面对:

Socket 文件描述符 内核缓冲区 用户态连接对象 网络带宽 TLS 事件循环 连接管理

所以更准确的说法是:

SSE 在单向流式场景下协议和业务模型更简单,但不能简单认为 SSE 天然比 WebSocket 省固定比例的 CPU 或内存。

真正需要优化时应该压测。


9. 为什么 WebSocket 在大规模连接下可能更复杂?

WebSocket 是双向长连接,服务端通常需要长期维护连接以及与连接关联的业务状态。

例如:

用户 ↓ WebSocket Connection ↓ 用户 Session ↓ 订阅关系 ↓ 消息状态 ↓ 发送队列

当连接数非常大的时候:

10 万 100 万 1000 万

连接管理本身就成为架构问题。尤其当业务状态直接绑定到某台机器:

Client ↓ Server A ↓ Connection State

这时候扩容成:

Server A Server B Server C

就必须考虑:

连接到底在哪台服务器? 业务消息在哪台服务器产生? 怎么找到对应连接? 服务器之间怎么通信?

10. SSE 是不是天然无状态?

不是。

这一点一定不要答错。SSE 只是通信方式。你完全可以设计成:

Client ↓ SSE ↓ Server ↓ 连接状态

也可以:

Client ↓ SSE ↓ Server ↓ Redis / MQ / DB ↓ 业务状态

所以:

SSE 不等于无状态,WebSocket 也不等于一定有状态。

更准确的是:

WebSocket 的持续双向连接更容易产生连接级状态,因此大规模水平扩展时,需要重点处理连接与业务状态的解耦。


11. SSE 怎么做水平扩展?

例如:

Load Balancer / | \ / | \ Server A Server B Server C \ | / \ | / Redis / MQ

假设:

用户的 SSE 连接 ↓ Server A

但是:

AI 模型生成结果 ↓ Server C

Server C 不能直接假设:

用户连接就在我这里。

所以可以:

AI Worker ↓ Redis / MQ ↓ Server A ↓ SSE ↓ Browser

这样:

AI 任务处理和 SSE 连接管理就可以解耦。

当然,具体用 Redis Pub/Sub、Stream、Kafka、消息队列还是其他方案,要根据可靠性、吞吐和数据生命周期选择。


12. SSE 能不能上传图片?

SSE 本身不负责文件上传。但是这完全不是问题。

例如:

┌──── HTTP Multipart ────► 文件服务 │ Client ──────┤ │ └──── Chat Request ──────► AI 服务 │ ▼ AI 推理 │ ▼ Client ◄──────────── SSE Stream ─────────────┘

也就是:

图片: HTTP 上传 AI 输出: SSE 流式返回

所以:

“AI 要上传图片,所以必须用 WebSocket”是错误的。

甚至大文件上传本身通常也更适合 HTTP,因为可以利用:

multipart 分片上传 断点续传 对象存储 CDN 上传进度

13. 那什么时候应该用 WebSocket?

这时候看业务。如果是:

用户发一个问题 ↓ AI 持续返回答案

优先考虑:

SSE

如果变成:

Client ◄════════════► Server

双方都需要持续、高频、实时通信:

用户操作 ↓ 服务器 ↓ 其他用户 服务器状态 ↓ 客户端 客户端控制指令 ↓ 服务器

就更适合 WebSocket。

典型场景:

实时协作

用户 A ↓ 修改文档 ↓ Server ↓ 用户 B / C / D

在线游戏

客户端 → 移动 客户端 → 攻击 客户端 → 技能 服务端 → 状态同步 服务端 → 战斗结果 服务端 → 其他玩家

双向实时控制

例如:

Client ⇄ AI Agent

客户端持续发送控制指令,同时服务端持续返回状态,这时候 WebSocket 就更自然。


14. AI 语音为什么又不一定适合 SSE?

这是很好的追问。假设是实时语音:

麦克风 ↓ 持续上传音频 ↓ 服务端 ↓ AI ↓ 持续返回音频 ↓ 扬声器

实际上是:

Client ◄══════════► Server

而且:

客户端持续上传 + 服务端持续返回

这是典型的双向实时通信。所以这类场景通常会考虑:

WebSocket

或者对实时媒体传输要求更高时考虑:

WebRTC

因此千万不要形成:

AI = SSE。

正确的是:

AI 文本对话很适合 SSE,但 AI 不等于 SSE。具体协议还是取决于通信模型。


15. SSE 还有一个非常重要的工程坑:代理缓冲

如果面试官继续往深处问,这个很容易区分是否真正做过 SSE。

SSE 要的是:

服务端生成一点 ↓ 马上发给浏览器

但如果中间代理把数据缓存起来:

Server ↓ Proxy ↓ 缓存 10KB ↓ 一次性返回 ↓ Browser

那么用户看到的就不是:

一个字一个字出来

而是:

等一会儿 ↓ 突然出来一大段

所以实际部署 SSE 时,要关注:

代理缓冲 响应压缩 空闲超时 连接超时 HTTP/2 / HTTP/3

例如 Nginx 场景通常需要关闭响应缓冲,否则流式效果可能被破坏。这个点比单纯背:

SSE 是单向,WebSocket 是双向

要高级很多。


16. AI 对话到底怎么选?

可以直接记这张图:

AI 通信需求 │ ┌───────────┴───────────┐ │ │ 服务端流式输出 双向实时通信 │ │ ▼ ▼ SSE WebSocket │ │ AI 文本生成 实时协作 流式回答 在线游戏 实时通知 双向控制 日志流 实时交互

如果进一步考虑:

双向实时音视频 ↓ WebRTC

所以协议选择可以简单理解成:

单向流式输出 → SSE 双向实时消息 → WebSocket 实时音视频媒体 → WebRTC

但这只是第一层判断,真正的工程选型还要继续考虑:

可靠性 连接规模 部署环境 代理/CDN 断线恢复 消息顺序 状态管理 扩展方式 开发维护成本

17. 这道题真正考什么?

它表面上问:

为什么 AI 对话用 SSE,而不是 WebSocket?

实际上考的是:

你能不能根据业务需求和工程约束做技术选型,而不是只会背 API。

普通回答:

SSE 单向,WebSocket 双向。

只能拿到基础分。更好的回答:

AI 文本对话本身就是客户端发起请求、服务端持续流式输出,所以 SSE 的通信模型更匹配;同时 SSE 基于 HTTP,浏览器有 EventSource 和自动重连能力,接入现有 HTTP 基础设施也比较自然。WebSocket 的优势在于双向实时通信,如果业务需要客户端和服务端持续高频交互,它反而更合适。

这才是完整的第一层。


18. 高频追问链

这道题建议直接按照下面这条链准备:

为什么 AI 用 SSE? ↓ SSE 和 WebSocket 的通信模型区别? ↓ SSE 为什么适合流式输出? ↓ SSE 为什么基于 HTTP? ↓ WebSocket 怎么建立连接? ↓ HTTP Upgrade 做了什么? ↓ SSE 怎么自动重连? ↓ Last-Event-ID 是干什么的? ↓ WebSocket 怎么做重连? ↓ SSE / WebSocket 谁更省资源? ↓ 100 万连接服务器扛不住怎么办? ↓ SSE 怎么水平扩展? ↓ 多服务器之间怎么传 AI 流? ↓ Redis / MQ 在这里干什么? ↓ SSE 能不能上传图片? ↓ AI 实时语音怎么办? ↓ 什么时候应该用 WebSocket? ↓ SSE 部署在 Nginx / CDN 后有什么坑?

19. 最终满分答案

如果面试官问:

“为什么 AI 对话普遍用 SSE,而不是 WebSocket?”

你可以直接回答:

AI 对话通常是客户端发一次请求,服务端持续把模型生成结果流回来,所以 SSE 的通信模型更匹配。它又是基于 HTTP 的,浏览器通过 EventSource 就能直接接收事件流,并且具备自动重连能力,所以整体接入和维护成本比较低。

WebSocket 当然也能做 AI 对话,只是它的优势主要是双向实时通信。如果业务需要客户端和服务端持续、高频地互相发送消息,比如实时协作、在线游戏、双向实时控制,那 WebSocket 更合适。

所以我不会简单认为 SSE 比 WebSocket 更好,而是看通信模型:服务端流式输出优先考虑 SSE,双向实时通信考虑 WebSocket;如果是实时音视频,还要进一步考虑 WebRTC。

这版的核心结论就是:不是“AI 必须用 SSE”,而是“AI 文本对话的通信模型刚好非常适合 SSE”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询