[特殊字符] 前端SSE流式传输技术:对话大模型的最佳拍档!
Server-Sent Events (SSE) 是一种允许服务器主动推送消息给客户端的技术。和WebSocket这个"电话"(双向通信)不同,SSE更像是个"广播喇叭"(单向通信),特别适合服务器需要不断推送信息的场景。技术特点📡 基于HTTP协议(不像WebSocket需要额外协议)🔄 每次消息发送后连接会关闭,客户端需要重新连接✉️ 消息格式有严格规范(后面会详细讲解)服务端升级版//
一、前言:为什么我们需要流式传输?
当我们在与ChatGPT、DeepSeek和Kimi这样的大模型应用"聊天"时,你有没有发现它们的回复不是一下子蹦出来的,而是像老式打字机那样逐字逐句地展现?这可不是为了制造悬念哦!🎬
技术揭秘时刻:大模型收到输入后并不是一次性生成最终结果,而是像挤牙膏一样逐步生成中间结果。那么问题来了——这种流畅的"打字机效果"是怎么实现的呢?是通过不断刷新的轮询?还是全双工的WebSocket?
正确答案是:SSE(Server-Sent Events)技术!这项技术让大模型能够像快递小哥一样,实时推送中间生成结果,带来双重优势:
-
⏱️ 缩短等待时间:不用等全部内容生成完就能看到部分结果
-
🛡️ 规避超时风险:长文本生成再也不怕请求超时啦!
下面就让咱们一起揭开这项"黑科技"的神秘面纱吧!🔍
二、SSE技术深度解析
什么是SSE?
Server-Sent Events (SSE) 是一种允许服务器主动推送消息给客户端的技术。和WebSocket这个"电话"(双向通信)不同,SSE更像是个"广播喇叭"(单向通信),特别适合服务器需要不断推送信息的场景。
技术特点:
-
📡 基于HTTP协议(不像WebSocket需要额外协议)
-
🔄 每次消息发送后连接会关闭,客户端需要重新连接
-
✉️ 消息格式有严格规范(后面会详细讲解)
SSE消息格式说明书
每条SSE消息就像一封信✉️,由多个字段组成,每个字段的格式为:
[field]: [value]\n
信件之间用两个换行符\n\n隔开,常见字段包括:
| 字段名 | 作用 | 示例 |
|---|---|---|
data |
消息内容 | data: Hello SSE!\n\n |
event |
自定义事件类型 | event: notification\n |
id |
事件唯一ID | id: 12345\n |
retry |
重连时间(ms) | retry: 5000\n |
代码示例:
// 发送简单消息
res.write('data: Hello, SSE!\n\n');
// 发送多行消息(会自动合并)
res.write('data: 第一行\n');
res.write('data: 第二行\n\n');
// 发送自定义事件
res.write('event: systemAlert\n');
res.write('data: 服务器即将维护!\n\n');
三、SSE实战手册
3.1 基础篇 - EventSource
场景1:简单消息推送
服务端代码:
app.get("/sse", (req, res) => {
// 必须设置的HTTP头部
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
// 每秒推送一次当前时间
setInterval(() => {
res.write(`data: ${new Date().toLocaleString()}\n\n`);
}, 1000)
});
客户端代码:
const eventSource = new EventSource("http://localhost:3000/sse");
eventSource.onmessage = (event) => {
console.log("收到消息:", event.data);
};
场景2:自定义事件处理
服务端升级版:
// 添加自定义事件
res.write('event: stockUpdate\n');
res.write('data: {"symbol":"AAPL","price":182.73}\n\n');
客户端监听:
eventSource.addEventListener("stockUpdate", (event) => {
const data = JSON.parse(event.data);
console.log(`股票${data.symbol}最新价格:$${data.price}`);
});
场景3:连接管理
优雅地分手:
// 服务端主动结束
res.end();
// 客户端主动关闭
eventSource.close();
// 错误处理
eventSource.onerror = (err) => {
console.error("SSE连接异常:", err);
eventSource.close();
};
3.2 进阶篇 - POST请求支持
默认的EventSource只支持GET请求,这就像只能用明信片通信📮,太不安全了!下面教你怎么用"加密信封"✉️:
方案1:Token中转站
async function getSecureSSE(url, data) {
// 第一步:用POST获取临时通行证
const { sseToken } = await fetch("/get-sse-token", {
method: "POST",
body: JSON.stringify(data)
}).then(res => res.json());
// 第二步:用Token建立SSE连接
return new EventSource(`/sse?token=${sseToken}`);
}
方案2:Fetch API黑科技
async function postSSE(url, data, callbacks) {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "text/event-stream",
},
body: JSON.stringify(data),
});
const reader = response.body.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
const text = new TextDecoder().decode(value);
callbacks.onMessage(text);
}
}
方案3:使用现成轮子
import { fetchEventSource } from "@microsoft/fetch-event-source";
fetchEventSource("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ question: "你好啊!" }),
onmessage(msg) {
console.log("AI回复:", msg.data);
}
});
四、技术选型大比拼
| 技术 | 通信方向 | 协议 | 复杂度 | 适用场景 |
|---|---|---|---|---|
| SSE | 服务器→客户端 | HTTP | ★★☆ | 实时通知、大模型对话 |
| WebSocket | 双向通信 | ws/wss | ★★★ | 聊天室、协同编辑 |
| 短轮询 | 客户端→服务器 | HTTP | ★☆☆ | 简单实时性要求低 |
| 长轮询 | 客户端→服务器 | HTTP | ★★☆ | 兼容性要求高 |
五、结语:SSE的未来展望
SSE技术正在这些领域大放异彩:
-
🤖 大模型对话:实现流畅的"打字机效果"
-
📈 金融实时数据:股价瞬息万变也不怕
-
📱 即时通讯:消息已读回执实时更新
-
🏗️ 长任务监控:构建进度条不再头疼
随着Web技术的演进,SSE这个"单向广播"能手,必将在实时通信领域继续发光发热!
思考题:如果你的应用需要实现以下功能,你会选择哪种技术?
-
股票价格实时看板 📉
-
在线多人白板协作 🎨
-
后台任务进度查询 ⏳
欢迎在评论区分享你的技术选型思路!💡
(本文完整代码示例可参考:streaming-learn)
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)