AI对话为什么都用SSE?WebSocket其实用错了地方

更新日期: 2026-04-06 阅读: 5 标签: SSE

做AI对话功能的时候,前后端怎么传数据是个绕不开的问题。轮询、SSE、WebSocket,到底该用哪个?

这篇文章把三种方式放在一起对比,看完你就能直接做出选型判断。


先记住三点

轮询是客户端反复问服务端要数据。SSE是服务端单向推送。WebSocket是双向通道。

AI对话用SSE就够了。单向推送满足需求,而且对服务器最友好。


轮询:最简单但最笨的办法

轮询的思路很简单。客户端写一个定时器,每隔几秒去问服务端:有新数据吗?

setInterval(async () => {
  const res = await fetch('/api/check');
  const data = await res.json();
  if (data.hasNew) updateUI(data.content);
}, 3000);

底层用的是普通HTTP。每次请求都经历建连、发请求、等响应、断开这一套流程。

但放到AI对话里,问题就来了。轮询间隔短了,大量用户同时高频请求会压垮服务器。间隔长了,流式输出又变得卡顿,打字机效果全没了。

不过轮询也不是没用。数据更新频率低、对实时性要求不高的场景完全够用。比如每30秒刷一次邮件列表,每分钟检查一下构建状态。


SSE:服务端单向推送

轮询是客户端不停问。那能不能反过来,让服务端主动推?

想象你点了一份外卖。下完单之后你不用反复刷,骑手每到一个节点,app自动通知你:已接单、已到店、配送中。

你只下了一次单,之后所有进度都是app主动推给你的。一次请求,服务端不断推,客户端只管接收。

浏览器为这种推送定义了一套标准格式。响应头必须是Content-Type: text/event-stream,每条消息以data:开头、\n\n结尾。

data: 今天
data: 天气
data: 不错

浏览器还提供了一个叫EventSource的API。只要连上,服务端推过来的消息它会自动解析好,你直接拿字符串就行:

const source = new EventSource('/api/stream');
source.onmessage = event => {
  console.log(event.data);
};

你不用自己读字节、自己解码,EventSource全包了。

那AI对话为什么不用EventSource?

EventSource有两个硬伤。

第一,只支持GET请求。AI对话需要用POST把对话历史发给服务端,GET做不到。

第二,不支持自定义请求头。你没法带Authorization token做鉴权。

所以AI对话场景,客户端基本都用fetch配合ReadableStream自己读数据。Vercel AI SDK的useChat底层也是这个方案。

业界说的SSE到底指什么?

这里有个容易搞混的地方。“SSE”这个词可以指两个不同层面的东西。

HTTP streaming是基础层,对格式没有要求。服务端持续写、客户端持续读,仅此而已。

标准SSE是在它上面加的规范:data前缀、event字段、空行分隔。

拿几个真实产品来看就清楚了。

DeepSeek用的是标准SSE。响应头里有Content-Type: text/event-stream,Chrome开发者工具会多出一个EventStream标签页,帮你把消息解析成表格。

ChatGPT也是标准SSE。但它几乎不用event:字段来区分消息类型,而是把type塞进每条data的JSON里,靠内部字段判断。

Google Gemini用的也是SSE的思路,但格式完全自定义。响应不是data格式,是一行一行的JSON数组。EventStream标签页也没有了。

这说明一件事:用不用标准SSE格式,是接入大模型API那层接口自己的选择,不是技术限制。

你自己实现的时候,可以按这个来定方向:

只传纯文本内容,标准SSE就够了。格式简单,浏览器有调试工具,前后端约定也直观。

需要在一个流里传多种数据(文字内容、工具调用结果、token统计、状态信息),自定义格式更实际。可以像ChatGPT那样在JSON里加type字段区分类型。


WebSocket:双向实时通道

还是点外卖的例子。轮询是你反复刷app。SSE是app主动推送骑手状态。

WebSocket呢?你不仅能实时收到骑手位置,还能在配送途中直接给骑手发消息:“放门口就行,不要打电话”。骑手也能马上回你:“好的”。

双方随时都能说话,不需要等对方先开口。这就是全双工。

代码写起来也很简洁:

const ws = new WebSocket('wss://example.com/chat');

ws.onmessage = event => {
  console.log('收到:', event.data);
};

ws.send('你好');
ws.send('再来一条');

和SSE最大的区别是:SSE客户端只能听,要“说话”得另发一次HTTP请求。WebSocket直接ws.send(),在同一条连接上双向通信。

WebSocket适合什么场景?

需要双向实时通信的场景:多人聊天室每个人都在发消息,协同编辑文档每个人的改动要实时同步,在线游戏里玩家操作和服务器状态需要持续互传。

共同点是客户端不只是在“听”,还需要频繁“说”,而且要低延迟。


三种方案怎么选?

低频状态查询选轮询。数据更新慢、实时性要求不高,用最简单的方案就够了。

AI对话选SSE。单向推送够用,HTTP原生支持,不用额外配置基础设施。你发出的是一条消息,然后等着看AI怎么回。整个过程里你不会再往服务端发任何数据,就是在等、在接收。单向推送完全够用。

而且SSE用的是普通HTTP。你现在用的CDN、反向代理、Serverless函数全都能直接支持,不需要任何额外配置。WebSocket就不一样了,它不走普通HTTP,CDN、Nginx、云函数这些中间层不一定默认支持,部署到线上要单独配置。

WebSocket还有一套要自己维护的东西:心跳检测、断线重连、连接状态管理。SSE不用管这些。

多人实时协作选WebSocket。双方都要频繁说话,需要真正的双向通道。

WebSocket和SSE不是谁更好的关系。它们是为不同场景设计的工具。

什么时候需要WebSocket?

一旦客户端也需要频繁往服务端发数据,SSE就不够用了。

比如你在做一个多人协同编辑加AI辅助的产品。协同编辑部分需要WebSocket,持续同步多人的操作。AI建议部分用SSE就够了,触发后单向推送回答。

同一个产品里不同的通信需求,用不同的方案,这在真实项目里很常见。


思考题

Q1:fetch + ReadableStream读流式数据和标准SSE的EventSource相比,各自适合什么场景?想想AI对话需要POST还是GET,需不需要自定义请求头。

Q2:你的项目里已经有WebSocket基础设施(比如用于实时通知),现在要加AI对话功能,你会复用WebSocket还是单独用SSE?想想AI对话的数据流向是单向还是双向,复用WebSocket多出来的维护成本换来了什么。

Q3:做一个实时协作文档产品,文档协同编辑和AI写作助手这两个功能,分别会选什么传输方案?想想这两个功能的通信方向有什么不同。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13594

相关推荐

前端实现AI对话:使用SSE技术提升实时交互体验

在现代前端开发中,AI智能对话功能越来越常见。实现这类功能时,关键是要让用户能够实时看到AI返回的内容,而不是等待全部生成完毕才显示。Server-Sent Events(SSE)技术为此提供了一种高效且易于实现的解决方案。

从 WebSocket 到 SSE:实时通信的轻量选择

在实时网络应用领域,WebSocket 一直被认为是首选方案。无论是聊天应用、在线游戏还是协同编辑工具,WebSocket 的强大双向通信能力都让它成为开发者的首选。

Nginx配置SSE和WebSocket代理的完整指南

在现代网站开发中,实时通信功能已经很常见了。无论是用SSE实现服务器向客户端推送消息,还是用WebSocket建立双向通信,当项目部署到线上环境时Nginx配置不对经常导致本地能运行,线上就失效的问题。

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!