当前位置: 首页 > web >正文

Ai网站流式渲染总结

本文从技术选型分析到网站实战,将项目Ai网站中流式渲染的技术进行拆解,对比分析SSE和websocket的实现。

1. SSE简介

SSE(Server-Sent Events)译为服务器推送事件,通过EventSource接口实现服务器推送通信。与webSocket不同的是,SSE基于http连接,为单向通信,在单向推送场景下(各大AI网站)得到很好的应用。一个 EventSource 实例会对 HTTP 服务器开启一个持久化的连接,以 text/event-stream 格式发送事件,此连接会一直保持开启直到通过调用 EventSource.close() 关闭。客户端开启EventSource连接后通过监听特定的事件(如notice,update,meessage)来处理相关的逻辑。

EventSource 的特点

  1. 单向通信:服务器向客户端推送消息,客户端不能向服务器发送消息。
  2. 文本流:数据以文本形式发送,通常是 UTF-8 编码。
  3. 自动重连:如果连接中断,浏览器会自动尝试重新连接。
  4. 事件命名:可以为消息指定不同的事件类型,客户端可以根据事件类型选择性地处理消息。

sse也有一定的缺陷:

  • 不支持双向通信。
  • 不支持二进制数据传输。
  • 兼容性存在问题,不支持 IE 浏览器。
  • 单个浏览器最大连接数限制

    当不使用 HTTP/2 时,服务器发送事件(SSE)受到打开连接数的限制,这个限制是对于浏览器的,并且设置为非常低的数字(6),打开多个选项卡时可能会特别痛苦。在 Chrome 和 Firefox 中,这个问题已被标记为“不会修复”。这个限制是每个浏览器和域名的,这意味着你可以在所有标签页中打开 6 个 SSE 连接到 http://www.example1.com,以及另外 6 个 SSE 连接到 http://www.example2.com(来源:Stackoverflow)。当使用 HTTP/2 时,最大并发 HTTP 流的数量是由服务器和客户端协商的(默认为 100)。

const response = await fetch(url, {method: "POST",headers: {"Content-Type": "application/json",Accept: "text/event-stream",},body: JSON.stringify(data),}).catch((err) => {console.log("err报错了", err);});// 获取 ReadableStream 并创建读取器const reader = response.body.getReader();}
使用TextDecoder 解码:

EventSource发送来的是utf-8编码的信息,通过reader.read()得到的value为字节流,我们还需要使用TextDecoder 解码器器将字节流作为输入,并提供码位流作为输出,这个过程可以称为翻译。

  const decoder = new TextDecoder();// 持续读取流数据while (true) {const { done, value } = await reader.read();if (done) {reader.releaseLock();break;} // 流结束console.log("字节流", value);const chunk = decoder.decode(value);console.log("解码后数据为", chunk);}

在AI网站上,我们通常会看到AI回答的内容有列表,有代码块,还有表格等等,通过观察他们的数据格式,通过引入markdown库来对返回信息进行解析,再实时更新页面,这就有了页面打字机和丰富的排版效果。

备注:SSE需要注意通信格式:每条信息后面需以\n\n结束(SSE协议规定的)。 EventSource 中,发送数据的行以冒号开头表示注释行。这些行是发送给客户端的非事件数据,浏览器会忽略它们,但它们有助于保持连接活跃:

// 保持连接,避免断开setInterval(() => {res.write(': keep-alive\n\n');}, 15000);

EventSource 发送数据时需要以特定的关键字开头,如 data、event、id、retry 和 :(注释行)

EventSource本质上还是Http协议,所有的Http协议都是用Http字段来跟浏览器谈心的,所以必须设置这几个header:status、content-type、cache-control、connection,不然浏览器不认识它。

 HTTP/1.1 协议默认开启持久连接(persistent connection),这意味着同一个 TCP 连接可以被重用来发送和接收多个 HTTP 请求和响应。然而,如果连接在一段时间内没有活动,某些中间网络设备(如防火墙、代理服务器)或客户端本身可能会认为连接已经闲置太久,从而关闭连接。所以需要定时发送心跳让浏览器别消灭它:res.write(': keep-alive\n\n')。

2.websocket

首先对比一下SSE 和 WebSocket 流式输出的特性:

SSE (Server-Sent Events)WebSocket
通信方向单向 (Server → Client) 双向 (Server ↔ Client)
协议HTTP/1.1 + EventSourceWebSocket 协议
连接方式基于 HTTP 长连接 需要单独 升级协议
消息格式纯文本(也支持 JSON)二进制 / JSON / 文本
断线重连浏览器自动重连需要手动实现重连逻辑
服务器推送天然支持(适合 AI 生成式内容需要额外实现
服务器压力轻量级(基于 HTTP/1.1)服务器需要维护更多连接
浏览器支持所有现代浏览器支持需要 支持 WebSocket
适用场景AI 流式输出、日志推送、股票行情等实时聊天、双向交互、多人协作等

通过上面的对比,不难得知SSE更适合Ai生成式项目,但为什么要使用WebSocket?与 SSE 相比,WebSocket 具有以下特点:

  1. 支持双向通信 , 客户端可以随时向服务器发送消息,而不仅仅是等待 AI 回复。
  2. 更低的连接开销 ,WebSocket 连接后,数据传输比 SSE 高效,适用于高并发场景。
  3. 支持二进制数据,可以更灵活地发送 JSON、二进制流,适配 AI 复杂交互。
  4. 连接状态可控 ,可以手动断开连接、重连、主动停止 AI 生成。

综合以上,如果你的项目需要支持更多的参数和互动效果,比如手动终止以及高并发场景Websocket是不错的选择😌。

    http://www.xdnf.cn/news/5636.html

    相关文章:

  • c语言第一个小游戏:贪吃蛇小游戏03
  • #在 CentOS 7 中手动编译安装软件操作及原理
  • 03.Golang 切片(slice)源码分析(二、append实现)
  • 视频监控汇聚平台EasyCVR安防视频监控小知识:视频监控系统与监视器安装
  • 【Redis实战篇】分布式锁-Redisson
  • 最新AI产品库哪个平台好?最新AI工具网站平台推荐
  • C++中的std::allocator
  • 神经生物学+图论双buff,揭示大脑语言系统的拓扑结构
  • Android学习总结之线程池篇
  • 脑机接口重点产品发展路径分析:以四川省脑机接口及人机交互产业攻坚突破行动计划(2025-2030年)为例
  • Matlab 短时交通流预测AR模型
  • 【C#】ToArray的使用
  • 将本地文件上传到云服务器上
  • Matlab 模糊控制节水洗衣机模型
  • Next.js 知识框架总结
  • 212. 单词搜索 II【 力扣(LeetCode) 】
  • windows下docker 运行 ros2humble arm64
  • day 23
  • VIC-2D 7.0 为平面样件机械试验提供全视野位移及应变数据软件
  • MySQL是如何加行级锁的
  • Java大师成长计划之第19天:性能调优与GC原理
  • C# 中 static的使用
  • 计算机网络核心技术解析:从基础架构到应用实践
  • 2025年阿里云大数据ACP高级工程师认证模拟试题(附答案解析)
  • 基于Vue3.0的高德地图api教程004:自定义绘制点的颜色/修改绘制点/删除绘制点
  • RCE联系
  • 什么是ERP?ERP有哪些功能?小微企业ERP系统源码,SpringBoot+Vue+ElementUI+UniAPP
  • 基于LVS和Keepalived实现高可用负载均衡架构
  • [Java实战]Spring Boot 整合 Redis(十八)
  • Browserless 快速上手