微信小程序接收stream流请求

前两天对接微信小程序ai的时候用到了stream流式请求。
先说一下个人理解的流式请求是什么吧,流式请求就是持续接收数据的请求,一般用post。
一般在传输大文件或者大数据,实时数据传输等等场景,这种方式可以节省内存。
这篇文章就是用到了实时数据传输,把ai回复的文字实时展示在客户端,可以实现打字机的效果。
我这里用的是硅基流动的api接口。

//声明一个接收二进制的变量,utf-8表示接收utf-8的编码。后续要这个变量来接收数据和转换数据
const utf8Decoder = new TextDecoder('utf-8')

//1:用uni.request发送请求,再声明一个变量接收它。
const requestTsk = uni.request({
    		url: url,
    		method: 'POST',
            //开启分块传输数据,这个一定要开,不开的话后续无法进行。
    		enableChunked: true,
    		header: {
    			'Content-Type': 'application/json',
    			'Authorization': 'Bearer ' + apiKey,
                //这个请求头告诉服务器前端要接收stream的数据流。可写可不写。
    			'Accept': 'text/event-stream'
    		},
    		data: {
                //模型配置
    			model: SILICONFLOW_CONFIG.model,
                //对话列表
    			messages: apiMessages,
    			max_tokens: SILICONFLOW_CONFIG.maxTokens,
    			// 这个是硅基流动开启stream的配置,只做参考。
                stream: true
    		},
    		success: (_res: UniNamespace.RequestSuccessCallbackResult) => {
   //3.这个success回调表示流式请求已经结束,这里只做 UTF-8 解码收尾 + 空内容兜底 + 关 loading
                //这里是最后再转码一次,由于一个中文汉字占3个字节,
所以有可能导致utf8Decoder里最后不是的一整个中文,可能是最后一个中文的一个字节,
由于解码器在收到不是完整中文字节的时候会先暂存字节,所以就会导致最后这个字节还处于暂存状态,
这行代码的意思就是让解码器把最后的一个字节吐出来,
然后再按照utf-8的标准解析为正常的文本字符串。stream: false是声明流式请求结束。
				const tail = utf8Decoder.decode(new Uint8Array(0), { stream: false })
    		},
    		fail: (err: UniNamespace.GeneralCallbackResult) => {
    			// 请求失败:有占位则改占位,否则新追加一条错误 AI 消息
    			const msg = (err.errMsg != null && err.errMsg.length > 0) ? err.errMsg : '网络请求失败,请检查网络与 API 配置'
    			if (streamMsgId > 0) {
    				updateMessageById(streamMsgId, (prev) => {
    					return {
    						id: prev.id,
    						text: msg,
    						sender: prev.sender,
    						timestamp: prev.timestamp,
    						showThinking: false,
    						reasoning: undefined,
    						reasoningExpanded: undefined
    					}
    				})
    			} else {
    				appendAIMessage(msg)
    			}
    			uni.showToast({ title: msg, icon: 'none' })
    			isTyping.value = false
    			isAwaitingReply.value = false
    			scrollToBottom()
    		}
    	})

2.监听分块传输的数据流,
requestTsk.onChunkReceived((res) => {
    		if (res.data == null) return
    		let chunkText = ''
                //由于用的是ts,这里先做一层声明,其实不写也行,这么写只不过是更加规范一些,而且提前已经断言了res.data是ArrayBuffer类型。
    			const uint8Array = new Uint8Array(res.data as ArrayBuffer)
                //用decode把二进制数据转换为正常文本。stream:true表示这是一个持续的数据流。
    			chunkText = utf8Decoder.decode(uint8Array, { stream: true })
    		    //这里log出来的chunkText就是解析完的纯文本请求数据,例如:"data:xxx",真正的数据还要根据情况后续自己去解析。
			console.log(chunkText,'侦听流式二进制数据')
                
    	})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值