微信小程序对接SSE接口记录
微信小程序对接SSE接口记录
- 需求:公司项目对接gpt,gpt产生的结果是分段返回,所以要求在产生结果时,有打字机的效果。原本是由定时器调用,后来优化改为服务端使用SSE接口。
- 小程序使用起来比较方便,但是要求小程序基本库的版本需要在2.20.2以上。文档地址移步这里
- 微信小程序代码
// 基础库为2.33.0const requestTask = wx.request({url: `xxxxxxxx`, // 需要请求的接口地址enableChunked: true // enableChunked必须为true})// 开发工具存在问题,使用真机测试const listener = data => {// data为返回的数据,可以在此对数据进行处理}// 监听服务端返回的数据requestTask.onChunkReceived(listener)// 移除监听 需传入与监听时同一个的函数对象requestTask.offChunkReceived(listener)
注意:
- 接收到的结果数据类型固定为arrayBuffer,需要开发者自己进行转换,可以使用下面方法进行转换。
function arrayBufferToString(arr){if(typeof arr === 'string') { return arr; } var dataview = new DataView(arr);var ints = new Uint8Array(arr.byteLength);for(var i=0;i<ints.length;i++){ints[i]=dataview.getUint8(i);}var str = '', _arr = ints; for(var i = 0; i < _arr.length; i++) {if (_arr[i]) {var one = _arr[i].toString(2), v = one.match(/^1+?(?=0)/); if(v && one.length == 8) {var bytesLength = v[0].length;var store = _arr[i].toString(2).slice(7 - bytesLength); for(var st = 1; st < bytesLength; st++) { if ( _arr[st + i]) {store += _arr[st + i].toString(2).slice(2); }} str += String.fromCharCode(parseInt(store, 2)); i += bytesLength - 1; } else { str += String.fromCharCode(_arr[i]); } }} return str;
}
- 微信开发工具中无法转换数据。可能是由于开发工具问题,在服务端返回的字符串中存在中文时,开发工具是无法正常转换的。但是在真机是正常的。如果需要在开发工具中实现转换,可以与服务端协商将数据进行URL编码返回。
- 服务端一次返回的结果,微信小程序有时会将其截开,并分两次返回。由于截开的位置并不固定,所以可能会存在转换ArrayBuffer时,出现结果异常的问题。使用SSE接口一般有两种需求:一种是将所有的结果累加起来、还有一种就是后面的结果覆盖前面的。在使用第一种时,每次的返回量不会太大,所以应该不会出现微信小程序截开两次返回的情况。但是第二种每次返回的接口都在逐渐增大,可能会出现这种情况,我就是第二种。我是使用下面方法解决
// 我的数据是json字符串,如果出现分开返回,在转json时,会出现报错,所以使用try处理
let timer = null
const listener = data => {try {// 上次结果出现报错 这次正常 清除延时器if (timer) {clearTimeout(timer)timer = null}// 小程序存在数据截开的情况 存五次数据if (arr.length > 4) {arr.shift()}// 这里要存储的是arrayBuffer,不能存储string数据arr.push(data.data)// 数据处理 .......} catch (e) {// 最后一次出现报错 三秒后重组数据timer = setTimeout(() => {const len = arr.lengthlet index = len - 2,data = arr[len - 1],result = nullwhile(index > -1) {// 从后往前 合并data = mergeArrayBuffers(arr[index], data)try{// 数据处理 .......index = -1}catch(e){index -= 1}}}, 3000)}}
// 合并arrayBuffer
function mergeArrayBuffers(buffer1, buffer2) {if (!buffer1) {return buffer2;} else if (!buffer2) {return buffer1;}var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);tmp.set(new Uint8Array(buffer1), 0);tmp.set(new Uint8Array(buffer2), buffer1.byteLength);return tmp.buffer;
}
- 由于是后面的结果覆盖前面的,我只需要处理最后一次结果,如果结果正常则不用处理。不正常再将前面存储的数据一一合并,再做处理。
- 通常一个中文是两个字节,所以可能会出现一个中文恰好被截开的情况,所以需要存储的是原数据
- 由于SSE特性,需要由用户端断开连接,所以在使用完毕时,需要调用
requestTask.abort()断开连接
ps: 此文章做个人平常记录
相关文章:
微信小程序对接SSE接口记录
微信小程序对接SSE接口记录 需求:公司项目对接gpt,gpt产生的结果是分段返回,所以要求在产生结果时,有打字机的效果。原本是由定时器调用,后来优化改为服务端使用SSE接口。小程序使用起来比较方便,但是要求…...
Ngrok 的绝佳替代品,内网穿透神器 Serveo
什么是 Serveo Serveo 是一个免费的内网穿透服务,Serveo 可以将本地计算机暴露在互联网上,官方声称其为 Ngrok 的绝佳替代品。 Serveo 其最大优点是使用现有的 SSH 客户端,无需安装任何客户端软件即可完成端口转发。 Serveo 工作原理很简单…...
网络知识点之-路由
路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程。路由工作在OSI参考模型第三层——网络层的数据包转发设备。路由器通过转发数据包来实现网络互连。虽然路由器可以支持多种协议(如TCP/IP、IPX/SPX、AppleTa…...
input 框如何移动光标,设置光标位置?
获取 input 光标位置 const inputDom document.getElementById("input") const selectionStart inputDom.selectionStart设置 input 光标 inputDom.focus() // focus() 异步,所以加了 setTimeout setTimeout(() > {const nextSelection selection…...
linux内核系统调用学习5:SYSCALL_DEFINE<0-6>
系统调用最大参数是6,由下面这个宏定义,位于文件include\linux\syscalls.h #define SYSCALL_DEFINE_MAXARGS 6 SYSCALL_DEFINE0(fork) fork:系统调用名。 SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) set_tid_address&#x…...
maven镜像仓库配置(多镜像自动切换)
大家在使用IDEA的时候会遇到这样的一个问题,就是在下载源代码和资源文档的时候,有些镜像仓库里面没有源代码和资源文档,然后会导致下载失败。 这时候就需要多个镜像仓库的地址了。 附上我自己的配置文件: <mirrors><!--…...
ChatGPT在智能监控和安防系统中的应用如何?
ChatGPT在智能监控和安防系统中有着广泛的应用潜力。智能监控和安防系统是利用人工智能和计算机视觉技术来实现对环境的实时监控和安全保障的系统。ChatGPT作为一种通用的预训练语言模型,可以在智能监控和安防系统中发挥以下作用: 1. **智能视频监控**&…...
【Spring Boot Admin】介绍以及使用
介绍 概述 Spring Boot Admin是一个监控工具,旨在以一种漂亮且易于访问的方式可视化Spring Boot Actuators提供的信息。 主要功能点 显示应用程序的监控状态应用程序上下线监控查看 JVM,线程信息可视化的查看日志以及下载日志文件动态切换日志级别Http…...
本地私有仓库部署、docker--harbor私有仓库部署和管理
部署本地私有仓库 拉取镜像 修改daemon.json配置文件 重启docker服务 创建容器 为镜像打标签 上传镜像 查看私有仓库 其他主机拉取私有仓库镜像 Docker--harbor私有仓库 (1)什么是Harbor Harbor 是 VMware 公司开源的企业级 Docker Registry 项目…...
java根据模板导出word
java根据模板导出word 日常开发中,常常会遇到各种各样的表格进行导出,比较好的办法就是提前弄好word模版,再通过遍历的方式进行导出文档 1、制作word模版 模版编写 内容替换 目标下面模版进行多页展示 将word转换成xml 将xml格式化 再将x…...
spring学习笔记十四
注解开发Bean总结 功能 xml配置注解定义Bean bean标签 id属性class属性 Component ControllerServiceRepositorComponentScan 设置依赖注入 setter注入(set方法) 引用类型/简单类型构造器注入 引用类型和简单类型自动装配 Autowired QualifierValue 配置第三方Bean be…...
【springmvc部分功能源码仿写第一步】实现java对目录下所有文件的遍历
废话不多说,直接上源码! public class MiniSpring {public static void main(String[] args) {String path "D:\\ideaProject\\thread";File file new File(path);List<String> list new ArrayList<>();System.out.println(fi…...
SpringBoot中接口幂等性实现方案-自定义注解+Redis+拦截器实现防止订单重复提交
场景 SpringBootRedis自定义注解实现接口防刷(限制不同接口单位时间内最大请求次数): SpringBootRedis自定义注解实现接口防刷(限制不同接口单位时间内最大请求次数)_redis防刷_霸道流氓气质的博客-CSDN博客 以下接口幂等性的实现方式与上面博客类似,…...
论文解读|用于从RGB-D数据进行3D物体检测的Frustum PointNets
原创 | 文 BFT机器人 01 摘要 论文研究了室内和室外场景中基于RGBD数据的3D目标检测。论文的方法不仅仅依赖于3D方案,而是利用成熟的2D对象检测器和先进的3D深度学习进行对象定位,即使是小对象也能实现高效率和高召回。 直接在原始点云中学习࿰…...
3ds Max图文教程: 使用动态工具Mass FX 创建风铃动画
推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 简单的场景设置 步骤 1 打开 3ds Max。 打开 3ds Max 步骤 2 我将向您展示风铃背后的动态 通过简单的场景设置进行模拟。一旦你有了这个想法,你就可以应用这个 技术到复杂的风铃结构。 基…...
抖音矩阵系统源码开发搭建部署分享
一、 功能开发设计 (1)数据概览:账号,视频top10数据统计 (2)AI视频创意:原创视频批量剪辑,阶乘算法,去重原理 (3)同城拓客:线下门店…...
Grafana图形web监控的安装与配置
目录 一、安装并配置 二、Web访问 三、Grafana启用zabbix插件 四、Grafana添加zabbix数据源 五、创建仪表盘 创建监控项完成保存仪表盘 六、查看创建的仪表盘 七、在现有的dashboard(仪表盘)中添加图形 八、查看最终dashborad(仪表盘&#x…...
【机器学习】了解 AUC - ROC 曲线
一、说明 在机器学习中,性能测量是一项基本任务。因此,当涉及到分类问题时,我们可以依靠AUC - ROC曲线。当我们需要检查或可视化多类分类问题的性能时,我们使用AUC(曲线下面积)ROC(接收器工作特…...
Docker 容器生命周期:创建、启动、暂停与停止----从创建到停止多角度分析
🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~ἳ…...
C++STL库中的vector
文章目录 vector的介绍及使用 vector深度剖析及模拟实现 动态二维数组理解 一、vector的介绍及使用 1.vector的介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
