使用 UniApp 在微信小程序中实现 SSE 流式响应
概述
服务端发送事件(Server-Sent Events, SSE)是一种允许服务器向客户端推送实时更新的技术。SSE 提供了一种单向的通信通道,服务器可以持续地向客户端发送数据,而不需要客户端频繁发起请求。这对于需要实时更新的应用场景非常有用。
流式传输的特点是将数据逐步传输给客户端,而不需要等待完整的响应生成。这意味着在传输过程中,数据会逐步发送给客户端,而不是一次性发送所有数据,对于基于文本的AI对话来说,这意味着每个单词或短语可以随着模型预测它们时即时显示出来,从而营造出一种更加自然和动态的交流体验。
最近在对接大模型对话生成接口,查找官方文档中并没有找到明确的实现说明,本文根据 Uniapp 及微信小程序开发文档,基于 uni.request 实现了一个简单的SSE客户端。
准备
服务端已提供SSE接口,可通过 Apifox 直接访问进行测试。
Uniapp 客户端实现
要实现在微信小程序中接收 SSE 流式响应,我们需要做几个关键步骤:
- 配置 HTTP 请求:设置适当的请求头和参数,以确保服务器知道我们期望的是流式响应。
- 处理分块数据:由于 SSE 是分块传输的,我们需要监听每个数据块,并适当地解析它们。
- 错误和完成处理:定义当遇到错误或完成时的行为。
下面是一个使用 uni.request API 实现 SSE 的例子:
let buffer = ''
function decode(data: ArrayBuffer): string {// 根据协议对数据进行解析,省略...// 注意数据可能是不连续的,需要通过 buffer 进行拼接
}function streamPost(url, data, onData, onError = null, onComplete = null) {function onChunkReceived(res) {onData(decode(res.data))}function onHeadersReceived(res) {console.log('onHeadersReceived', res)}const requestTask = uni.request({url: baseUrl + apiPath + url,method: 'POST',header: {Accept: 'text/event-stream', // 确保服务器知道我们期望的是流式响应Authorization: uni.getStorageSync('token'),// ...其他参数},data,enableChunked: true, // onChunkReceived, 否则走success()responseType: 'arraybuffer',success: (res) => {console.log('Data received:', res.data) // 开启 enableChunked 时仅最后一次会走这个},fail: (error) => { // 错误处理if (onError) {onError(error)}console.error('SSE failed:', error)},complete: () => { // 完成接收if (onComplete) {onComplete()}if (onHeadersReceived) {requestTask?.offHeadersReceived(onHeadersReceived)}if (onChunkReceived) {// @ts-expect-error uni-app types lostrequestTask?.offChunkReceived(onChunkReceived)}},})if (onHeadersReceived) {requestTask.onHeadersReceived(onHeadersReceived)}if (onChunkReceived) {// @ts-expect-error uni-app types lostrequestTask.onChunkReceived(onChunkReceived) // 注册数据接收响应函数}return requestTask // 外部可通过 requestTask.abort(); 主动结束
}
在 nginx 中开启transfer_encoding, 同时关闭缓存 proxy_buffering。
location /ai/chat/stream {proxy_set_header Transfer-Encoding "";chunked_transfer_encoding on;proxy_buffering off;
}
总结
- 开启:
enableChunked: true
- 设置请求 Header:
Accept: 'text/event-stream'
- 注册数据接收响应函数:
requestTask.onChunkReceived(onChunkReceived)
- 主动结束:
requestTask.abort()
- 分块数据解析:
decode()
通过以上步骤,我们成功地在 UniApp 中实现了 SSE 流式响应,增强了应用程序的实时交互能力。希望这篇文章能为你在 UniApp 中集成实时数据更新功能提供有价值的参考。
参考
- uniapp api 文档: https://uniapp.dcloud.net.cn/api/request/request.html
- 小程序开发文档:wx.request https://developers.weixin.qq.com/miniprogram/dev/api/network/request/RequestTask.onChunkReceived.html
欢迎合作
最近业余在做的个人项目:https://www.aaronzzh.cn
如果这篇文章对您有所帮助,欢迎点赞、分享和留言,让更多的人受益。感谢您的细心阅读,如果发现了任何错误或需要补充的地方,请随时告诉我,我会尽快处理 _
相关文章:

使用 UniApp 在微信小程序中实现 SSE 流式响应
概述 服务端发送事件(Server-Sent Events, SSE)是一种允许服务器向客户端推送实时更新的技术。SSE 提供了一种单向的通信通道,服务器可以持续地向客户端发送数据,而不需要客户端频繁发起请求。这对于需要实时更新的应用场景非常有…...
transformer用作分类任务
系列博客目录 文章目录 系列博客目录1、在手写数字图像这个数据集上进行分类1. 数据准备2. 将图像转化为适合Transformer的输入3. 位置编码4. Transformer编码器5. 池化操作6. 分类头7. 训练8. 评估总结流程:相关模型: 1、在手写数字图像这个数据集上进行…...
【枚举】假币问题
题目描述: 有12枚硬币。其中有11枚真币和1枚假币。假币和真币重量不同,但不知道假币比真币轻还是重。现在,用一架天平称了这些币三次,告诉你称的结果,请你找出假币并且确定假币是轻是重(数据保证一定能找出…...

easyExcel导出大数据量EXCEL文件,前端实现进度条或者遮罩层
需求:页面点击导出,先按照页面条件去数据库查询,然后将查询到的数据导出。 问题:由于查询特别耗时,所以点击之后页面会看上去没有反应 方案1:就在点击之后在页面增加了一个进度条,等待后端查询…...

Java模拟Mqtt客户端连接Mqtt Broker
Java模拟Mqtt客户端基本流程 引入Paho MQTT客户端库 <dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.mqttv5.client</artifactId><version>1.2.5</version> </dependency>设置mqtt配置数据 …...

【电商搜索】文档的信息论生成聚类
【电商搜索】文档的信息论生成聚类 目录 文章目录 【电商搜索】文档的信息论生成聚类目录文章信息概览研究背景技术挑战如何破局技术应用主要相关工作与参考文献后续优化方向 后记 文章信息 https://arxiv.org/pdf/2412.13534 概览 本文提出了一种基于信息论的生成聚类&#…...

在福昕(pdf)阅读器中导航到上次阅读页面的方法
文章目录 在福昕(pdf)阅读器中导航到上次阅读页面的方法概述笔记用书签的方法来导航用导航按钮的方法来导航 备注END 在福昕(pdf)阅读器中导航到上次阅读页面的方法 概述 喜欢用福昕(pdf)阅读器来看pdf文件。 但是有个小问题困扰了我好久。 e.g. 300页的pdf看了一半ÿ…...

基于Springboot的数字科技风险报告管理系统
博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有实…...
【最后203篇系列】001 - 2024回顾
说明 最早在CSDN上写文章有两个目的: 1 自己梳理知识,以备日后查用2 曾经从别人的文章中得到过帮助,所以也希望能给人帮助 所以在这个过程中,我的文章基本上完全是原创,也非常强调落地与工程化。在不断写作的过程中…...

量子退火与机器学习(1):少量数据求解未知QUBO矩阵,以少见多
文章目录 前言ー、复习QUBO:中药配伍的复杂性1.QUBO 的介入:寻找最佳药材组合 二、难题:QUBO矩阵未知的问题1.为什么这么难? 三、稀疏建模(Sparse Modeling)1. 欠定系统中的稀疏解2. L1和L2的选择: 三、压缩感知算法(C…...
矩阵:Input-Output Interpretation of Matrices (中英双语)
矩阵的输入-输出解释:深入理解与应用 在线性代数中,矩阵与向量的乘积 ( y A x y Ax yAx ) 是一个极为重要的关系。通过这一公式,我们可以将矩阵 ( A A A ) 看作一个将输入向量 ( x x x ) 映射到输出向量 ( y y y ) 的线性变换。在这种…...

excel 使用vlook up找出两列中不同的内容
当使用 VLOOKUP 函数时,您可以将其用于比较两列的内容。假设您要比较 A 列和 B 列的内容,并将结果显示在 C 列,您可以在 C1 单元格中输入以下公式: 这个公式将在 B 列中的每个单元格中查找是否存在于 A 列中。如果在 A 列中找不到…...
YoloV8改进策略:Head改进|DynamicHead,利用注意力机制统一目标检测头部|即插即用
摘要 论文介绍 本文介绍了一种名为DynamicHead的模块,该模块旨在通过注意力机制统一目标检测头部,以提升目标检测的性能。论文详细阐述了DynamicHead的工作原理,并通过实验证明了其在COCO基准测试上的有效性和效率。 创新点 DynamicHead模块的创新之处在于它首次尝试在一…...

两地的日出日落时间差为啥不相等
悟空去延吉玩耍,在下午4点多的时候发来一张照片,说,天已经黑了!我赶紧地图上看了看,延吉居然和北京差了大约15度的经度差,那就是大约一小时的时差哦。次日我随便查了一下两地的日出日落时间,结果…...
Android Https和WebView
系统会提示说不安全,因为网站通过js就能调用你的android代码,如果你确认你的网站没用到JS的话就不要打开这个开关,如果用到了,就添加一个注解忽略它就行了。 后来就使用我们公司的网站了,发现也出不来,后来…...

2.5.1 文件管理基本概念
文章目录 文件文件系统文件分类 文件 文件:具有符号名,逻辑上有完整意义的一组相关信息的集合。 文件包含文件体、文件说明两部分。文件体存储文件的真实内容,文件说明存放操作系统管理文件所用的信息。 文件说明包含文件名、内部标识、类型、…...

在 PowerShell 中优雅地显示 Python 虚拟环境
在使用 Python 进行开发时,虚拟环境管理是一个非常重要的部分。无论是使用 venv 还是 conda,我们都希望能够清晰地看到当前所处的虚拟环境。本文将介绍如何在 PowerShell 中配置提示符,使其能够优雅地显示不同类型的 Python 虚拟环境。 问题…...

K8S Ingress 服务配置步骤说明
部署Pod服务 分别使用kubectl run和kubectl apply 部署nginx和tomcat服务 # 快速启动一个nginx服务 kubectl run my-nginx --imagenginx --port80# 使用yaml创建tomcat服务 kubectl apply -f my-tomcat.yamlmy-tomcat.yaml apiVersion: apps/v1 kind: Deployment metadata:n…...

观察者模式(sigslot in C++)
大家,我是东风,今天抽点时间整理一下我很久前关注的一个不错的库,可以支持我们在使用标准C的时候使用信号槽机制进行观察者模式设计,sigslot 官网: http://sigslot.sourceforge.net/ 本文较为详尽探讨了一种观察者模…...

python使用pip进行库的下载
前言 现如今有太多的python编译软件,其库的下载也是五花八门,但在作者看来,无论是哪种方法都是万变不离其宗,即pip下载。 pip是python的包管理工具,无论你是用的什么python软件,都可以用pip进行库的下载。 …...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
JavaScript 标签加载
目录 JavaScript 标签加载script 标签的 async 和 defer 属性,分别代表什么,有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...
window 显示驱动开发-如何查询视频处理功能(三)
D3DDDICAPS_GETPROCAMPRANGE请求类型 UMD 返回指向 DXVADDI_VALUERANGE 结构的指针,该结构包含特定视频流上特定 ProcAmp 控件属性允许的值范围。 Direct3D 运行时在D3DDDIARG_GETCAPS的 pInfo 成员指向的变量中为特定视频流的 ProcAmp 控件属性指定DXVADDI_QUER…...