AIGC 在前端流式获取内容SSE
AIGC 在前端流式获取内容SSE
- 简介
- 具体实现
简介
在 OpenAI 的 API 中,SSE 通常用于实现实时数据传输。例如,在聊天模型(如 ChatGPT)中,使用 SSE 可以让客户端实时接收到生成的对话内容,而不需要等待整个响应完成。
EventSource会发送一个get类型的http请求,也可以通过fetch实现post类型的请求。我们这里使用fetch,SSE本质是字节流的传输,fetch中处理对应的字节流信息,同样可以实现EventSource的功能
SSE即Server-Sent
是HTML5提出一个标准。由客户端发起与服务器之间创建TCP连接,然后并维持这个连接,直到客户端或服务器中的任何一方断开。HTTP响应内容有一种特殊的content-type:text/event-stream
,该响应头标识了响应内容为事件流,客户端不会关闭连接,而是等待服务端不断得发送响应结果。
服务器通过 SSE 向客户端发送的每条消息通常包含以下几部分:
- 事件类型(可选):指定事件的类型。
- 数据:事件的主要数据内容。
- ID(可选):事件的唯一标识符。
- 重试时间(可选):客户端在连接断开后重试连接的时间间隔。
每条消息以两个换行符(\n\n)结束。
// sse 返回数据模型如下data:{"id":"1805489381010771970","object":"chat.completion.chunk","created":1719297188,"model":"gpt-4o-2024-05-13","choices":[{"index":0,"delta":{"role":"assistant","content":""},"message":null,"finishReason":null}],"usage":null}data:{"id":"1805489381010771970","object":"chat.completion.chunk","created":1719297188,"model":"gpt-4o-2024-05-13","choices":[{"index":0,"delta":{"content":"你好"},"message":null,"finishReason":null}],"usage":null}data:{"id":"1805489381010771970","object":"chat.completion.chunk","created":1719297188,"model":"gpt-4o-2024-05-13","choices":[{"index":0,"delta":{"content":"!"},"message":null,"finishReason":null}],"usage":null}data:{"id":"1805489381010771970","object":"chat.completion.chunk","created":1719297188,"model":"gpt-4o-2024-05-13","choices":[{"index":0,"delta":{},"message":null,"finishReason":"stop"}],"usage":null}data:[DONE]
具体实现
提示:关于流式获取,我们在业务开发中如果后端服务正常的话响应头Content-Type会是text/event-stream,否则为application/json。
封装一个工具方法来处理流式内容,并且在该方法中,使用者可以通过回调函数的形式来获取内容、状态等信息。
注意:需要通过fetch来创建请求,请求完成之后body为ReadableStream,可以获取它的读取器,一块一块的来读取数据,由于读取的数据为字节流数据,所以需要把字节流转换成字符串。为了更好的解析sse响应数据,这里使用了eventsource-parser第三方库,在读取过程中来拼接文本内容
import { ParseEvent, createParser } from 'eventsource-parser';
import emitter, { EmitterEvents } from './emitter';interface Options<T> {params?: T;onSucess?: (text: string, done: boolean, streamData: { id: string } | null) => void;onError?: (error: { code: number; msg: string }) => void;
}const sse = async function <T>(url: string, options?: Options<T>) {const userInfo = JSON.parse(localStorage.getItem('userInfo') ?? '{}');let responseText = '';let streamData: any = null;if (!userInfo?.jwt) {// 处理无tokenemitter.emit(EmitterEvents.ON_LOGIN, true);return;}function onParse(event: ParseEvent) {if (event.type === 'event') {const data = event.data;if (data === '[DONE]') {options?.onSucess?.(responseText, true, streamData);return;}streamData = JSON.parse(data);const text = streamData.choices[0].delta?.content || '';responseText += text;// 尝试解析敏感词检测结果try {const match = responseText.match(/```json\n(.*?)"code":10013(.*?)```/g);if (match) {const jsonStr = match.pop()!.replace(/```json\n/, '').replace(/```$/, '');const sensitiveObj = JSON.parse(jsonStr);if (sensitiveObj.DONE === 'DONE') {responseText = sensitiveObj.filteredText || '**';return;}}} catch (e) {console.log(e);}options?.onSucess?.(responseText, false, streamData);}}const res = await fetch(url, {method: 'POST',headers: {'Content-Type': 'application/json',token: userInfo.jwt,},body: JSON.stringify(options?.params),});if (res.ok) {const contentType = res.headers.get('Content-Type') ?? '';if (!contentType.includes('stream')) {const data = await res.json();options?.onError?.({ code: data.code, msg: data.msg });return;}const parser = createParser(onParse);const reader = res.body?.getReader();const decoder = new TextDecoder();while (true) {const content = await reader?.read();const decodeContent = decoder.decode(content?.value);if (content?.done) {break;}parser.feed(decodeContent);}} else {options?.onError?.({ code: res.status, msg: res.statusText });}
};export default sse;
相关文章:
AIGC 在前端流式获取内容SSE
AIGC 在前端流式获取内容SSE 简介具体实现 简介 在 OpenAI 的 API 中,SSE 通常用于实现实时数据传输。例如,在聊天模型(如 ChatGPT)中,使用 SSE 可以让客户端实时接收到生成的对话内容,而不需要等待整个响…...

深度解析安全阀检测技术:方法与挑战
在工业生产中,安全阀作为防止压力容器和管道发生过压事故的关键部件,其性能和可靠性对于保证设备安全和人员安全具有重要意义。随着工业化进程的不断深入,对安全阀的检测和维护工作也日益受到重视。 接下来,佰德旨在探讨安全阀检…...
网络安全--安全设备(一)Dos
安全设备--Dos 一、Dos 是什么二、DDos是什么三、Dos&DDos的区别四、产品防御Dos&DDos方式五、常见的DDoS攻击类型包括但不限于以下几种: 一、Dos 是什么 Dos(拒绝服务攻击,Denial-of-Service),是一种试图通过压倒网络或服务器来阻止合法用户访…...
<电力行业> - 《第3课:国家电网公司100条名词解释》
序号术语解 释1十不干一、无票的不干;二、工作任务、危险点不清楚的不干;三、危险点控制措施未落实的不干;四、超出作业范围未经审批的不干;五、未在接地保护范围内的不干;六、现场安全措施布置不到位、安全工器具不合…...

“论数据访问层设计技术及其应用”写作框架,系统架构设计师
论文真题 在信息系统的开发与建设中,分层设计是一种常见的架构设计方法,区分层次的目的是为了实现“高内聚低耦合”的思想。分层设计能有效简化系统复杂性,使设计结构清晰,便于提高复用能力和产品维护能力。一种常见的层次划分模…...

Docker部署前端,动态配置后端地址
本文介绍了使用Docker环境变量动态配置nginx。采用的是通过docker run -e xxxxxxx先往容器注入环境变量,然后进一步通过envsubst指令将环境变量写入到conf文件中,实现动态配置文件内容。 背景 前后端分离的架构下,经常会用到nginx反向代理来…...
k8s强制删除一个 Pod
在Kubernetes(K8s)中强制删除一个Pod,通常是因为Pod处于错误状态或无法正常终止。以下是强制删除Pod的步骤和相关信息: ### 步骤一:获取Pod的名称 首先,你需要知道要删除的Pod的名称。可以使用kubectl get …...
docker的安装配置及使用
一.Docker的由来 Docker 最初是 dotCloud 公司创始人Solomon Hykes 在法国期间发起的一个公司内部项目。 2010年的专门做PAAS平台,但是到了2013年的时候,像亚马逊,微软,Google都开始做PAAS平台。 到了2013年,公司资金链…...

初阶 《操作符详解》 10. 逗号表达式
10. 逗号表达式 exp1, exp2, exp3, …expN 注: 1.逗号表达式,就是用逗号隔开的多个表达式 2.逗号表达式,从左向右依次执行,整个表达式的结果是最后一个表达式的结果 代码1 #include <stdio.h> int main() {int a 1;int b…...
【区分vue2和vue3下的element UI Loading 加载组件,分别详细介绍属性,事件,方法如何使用,并举例】
首先,需要澄清的是,Element UI 是为 Vue 2 设计的,而 Element Plus 是 Element UI 的 Vue 3 版本。在 Element UI 和 Element Plus 中,并没有一个直接名为 “Loading 加载” 的独立组件。相反,加载效果通常是通过指令、…...

数据结构:栈(stack)详解 c++信息学奥赛基础知识讲解
目录 一、栈的定义 二、栈的操作 三、代码实操 四、栈的实现 1、string实现stack 2、vector实现stack 3、deque实现栈 一、栈的定义 stack是一个比较简单易用的数据结构,stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中ÿ…...
电商返利系统的高并发处理与性能优化
电商返利系统的高并发处理与性能优化 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 在电子商务平台中,返利系统是吸引用户和提升用户粘性的重要功…...
NPM 常用命令
NPM 常用命令 NPM(Node Package Manager)是 JavaScript 生态系统中最流行的包管理工具,它不仅可以管理 Node.js 项目的依赖,还提供了丰富的命令来管理和发布你的代码。本文将从不同角度,深入浅出地介绍 NPM 的常用命令…...

C++进修——C++核心编程
内存分区模型 C程序在执行时,将内存大方向划分为4个区域 代码区:存放函数体的二进制编码,由操作系统进行管理全局区:存放全局变量和静态变量以及常量栈区:由编译器自动分配释放,存放函数的参数值ÿ…...
【信息系统项目管理师知识点速记】项目文档管理
19.3 项目文档管理 信息系统相关信息(文档)是指某种数据媒体和其中所记录的数据。文档具有永久性,并可以由人或机器阅读,通常用于描述人工可读的内容。在软件工程中,文档常常用来表示对活动、需求、过程或结果进行描述、定义、规定、报告或认证的任何书面或图示的信息(包…...
服务器硬件,raid配置
文章目录 服务器硬件RAID磁盘阵列RAID 0RAID 1RAID 5RAID 6RAID 10 阵列卡,阵列卡的缓存阵列卡阵列卡的缓存 软RAID磁盘阵列RAID阵列的管理及设备恢复mdadm 服务器硬件 处理器(CPU):服务器的核心组件,负责执行计算和指令操作。服务器常使用多…...
fc-list命令使用指南
fc-list命令使用指南 一、什么是fc-list? fc-list是FontConfig库的一部分,最初为Linux和其他Unix-like系统开发。我们可以用这个命令行快速查询和列出系统中安装的字体。 现在,Windows用户也集成了这个工具,所以我们来讲解一下用法。 二、…...

NAS安全存储怎样实现更精细的数据权限管控?
NAS存储,即网络附属存储(Network Attached Storage),是一种专用数据存储服务器,其核心特点在于将数据存储设备与网络相连,实现集中管理数据的功能。 NAS存储具有以下明显优势,而被全球范围内的企…...

第三十篇——等价性:如何从等价信息里找答案?
目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 知道了等价性的逻辑,通过等价性去衡量事物,像是给…...

RabbitMQ实践——搭建多人聊天服务
大纲 用户登录创建聊天室监听Stream(聊天室)发送消息实验登录Tom侧Jerry侧 创建聊天室Jerry侧Tom侧 进入聊天室Jerry侧Tom侧 发送消息Jerry发送消息Jerry侧聊天室Tom侧聊天室 Tom发送消息Jerry侧聊天室Tom侧聊天室 代码工程参考资料 在《RabbitMQ实践——…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...

实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...