微信小程序-处理流式请求(sse)
·
一、微信小程序-处理流式请求(sse)
目前AI比较火热,很多小程序都接入了AI功能,但是对于AI对话,很多都是使用websocket的解决方案,但是会带来一些复杂度,前后端都需要维护连接的状态。因此AI对话主流方案还是使用sse,相对比较简单和轻量。本文将会介绍微信小程序接入sse的简单示例。
二、基于RequestTask.onChunkReceived,实现流式数据处理
2.1、index.js
// index.js
// 请求任务
let task = null;
Page({
data: {
msg: ''
},
// 取消请求
cancelRequest() {
if (task) {
console.log('cancel')
task.abort()
}
},
// 发起请求
startRequest() {
// 初始化消息内容,可忽略
this.setData({
msg: ''
});
// 实际发起请求,本文示例使用coze
task = wx.request({
url: 'https://api.coze.cn/v3/chat?conversation_id=7519696701909794856',
header: {
'content-type': 'application/json',
'Authorization': 'Bearer pat_Ey1d7Ix9urMKVE99xd7doplsMGAhE4UpwDqe7mP9F5mACb1mJB39q3zAf06p1UQn'
},
method: 'POST',
enableChunked: true,
data: {
"bot_id": "7478216525708247078",
"user_id": "123456",
"stream": true,
"additional_messages": [
{
"role": "user",
"type": "question",
"content_type": "text",
"content": "你好"
}
]
},
responseType:'arraybuffer',
success: (res) => {
// 请求完成回调用
},
});
// 缓存数据
let buffer = '';
task.onChunkReceived((res) => {
// 由于返回数据为二进制,需要进行解析
const chunk = this.decodeChunk(res.data);
if (!chunk) return;
buffer += chunk;
if (buffer.includes('\n\n')) {
this.parseSSEData(buffer);
buffer = '';
}
});
},
// 处理sse数据
parseSSEData(text) {
const messages = text.split('\n\n');
for (const message of messages) {
// 这里需要根据实际sse内容进行处理
if (!message.includes('event:conversation.message.delta')) continue;
const dataMatch = message.match(/data:(.+)/);
if (!dataMatch) continue;
try {
const jsonData = JSON.parse(dataMatch[1]);
this.setData({
msg: this.data.msg + jsonData.content
});
} catch (e) {
console.error('JSON解析错误:', e);
}
}
},
// 解析二进制数据
decodeChunk(data) {
// 兼容处理,真机返回的的是 ArrayBuffer
if (data instanceof ArrayBuffer) {
data = new Uint8Array(data);
}
try {
// 由于小程序真机不支持TextEncoder/TextDecoder,因此需要使用其他方式
return decodeURIComponent(escape(String.fromCharCode.apply(null, data)));
} catch (e) {
console.error('解码错误:', e);
return '';
}
},
})
2.2、index.wxml
<!--index.wxml-->
<scroll-view class="scrollarea" scroll-y type="list">
<view class="container">
<view class="text-box" scroll-y="true" scroll-top="{{scrollTop}}">
<text>{{msg}}</text>
</view>
<button bindtap="startRequest">发起请求</button>
<button bindtap="cancelRequest">取消请求</button>
</view>
</scroll-view>
2.3、显示效果


更多推荐
所有评论(0)