最近公司在做一款小程序,其中最主要业务的体现方式就是“与AI对话”,那一定是绕不过有着打字机效果的流式传输了。
什么是流式传输?
在解决问题之前,我们需要了解什么是流式传输。流式传输指的是将数据分成多个数据流,通过网络传输,以减少网络延迟和提高性能。在某些情况下,流式传输也可以用于将视频流和音频流传输到客户端。流式传输是一种高效的数据传输方式,常用于大文件下载和在线视频播放等。
解决方案
微信小程序请求不支持接受stream流
开始时尝试在wx.request方法请求体中加入responseType: 'stream'等方法进行实现,发现在 success 回调中返回的是最后的完整结果,而不是实时返回的,显然这种方法不行~
真正的可行方案:
onChunkReceived
微信官方文档中提到,wx.request中支持onChunkReceived分段式传输,在小程序中发起请求时,开启 enableChunked,并监听onChunkReceived的回调,逐步处理接收到的数据块,并将处理好的字符串逐步加入到数据中。这种方式有效地应对了微信小程序请求不支持stream流的问题。
代码实现
const requestTask = wx.request({ url: 'xxx', method: 'GET', responseType: "arraybuffer", enableChunked: true, //关键!开启流式传输模式 header: { 'content-type': 'application/json', }, data: { "prompt": '我梦见了一只金毛抢我的篮球', }, success: (res) => { console.log("结束----request success", res); }, fail: (err) => { console.log("request fail", err); }, }); // 监听请求头接受事件 requestTask.onHeadersReceived(r => { }); // 监听数据分块接收事件 requestTask.onChunkReceived((response) => { console.log('response',response) // 收到流式数据,根据返回值进行相对应数据解码 let data16 = app.buf2hex(response.data) let responseText = app.hexToStr(data16) // 将处理好的字符串加入到数据中 this.setData({ text: this.data.text + responseText }) });
要点1: 将enableChunked设置为true
要点2: 监听onChunkReceived的回调
要点
通过在请求中设置enableChunked: true和监听onChunkReceived回调,解决了微信小程序中不支持stream流的流式传输问题。
以上,就解决了我们的流式传输问题。
/** * 将 ArrayBuffer 转换为十六进制字符串 * @param {ArrayBuffer} buffer - 待转换的 ArrayBuffer * @returns {string} - 转换后的十六进制字符串 */ buf2hex(buffer) { return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join(''); }, /** * 将十六进制字符串转换为普通字符串 * @param {string} hex - 十六进制字符串 * @returns {string} - 转换后的普通字符串 */ hexToStr(hex) { let str = ''; for (let i = 0; i < hex.length; i += 2) { str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); } return str; }
通过开启enableChunked并监听onChunkReceived回调,我们可以逐步处理接收到的数据块,并将其整合到最终的数据中。
值得注意的是,在使用uniapp框架时,应选用wx.request而非uni.request。因为uni.request在处理流式数据时可能存在问题,而wx.request则能更好地应对这种情况。

△ 数据处理关键函数解析
在实现流式传输的过程中,数据处理函数扮演着至关重要的角色。这些函数负责接收、整合并处理从服务器分段传输过来的数据块,最终将其组合成完整的数据。在微信小程序中,我们可以通过wx.request的enableChunked选项和onChunkReceived回调函数来灵活处理这些数据块,从而实现高效的流式传输。

△ 辅助函数
在数据处理的过程中,除了核心的传输与处理函数外,还有一些辅助函数发挥着不可或缺的作用。这些辅助函数可能用于数据的预处理、格式转换、错误检测等,它们与关键函数协同工作,确保数据处理的流畅与准确。

浙公网安备 33010602011771号