通过uniapp开发与大模型对话的微信小程序,并且后端需要通过SSE向小程序返回响应数据。
微信小程序端需要展示响应数据,在这个过程中,数据解析这里踩了不少坑。
uniapp端开发微信小程序时,SSE连接处理的代码如下:
javascript
const initSSE2 = () => {
console.log(uni.getStorageSync('token'))
requestTask = uni.request({
url: 'http://127.0.0.1:8889/connect',
timeout: 30000,
responseType: 'text',
method: 'POST',
enableChunked: true, //配置这里
header: {
Accept: 'text/event-stream',
'Authorization': uni.getStorageSync('token') //自定义请求头信息
},
responseType: 'arraybuffer',
data: {},
success: response => {
console.log("success:" + JSON.stringify(response))
},
fail: error => {
console.log("error:" + JSON.stringify(error))
}
})
requestTask.onHeadersReceived((res) => {
console.log("header:" + JSON.stringify(res.header));
});
// 这里监听消息
requestTask.onChunkReceived((res) => {
const uint8Array = new Uint8Array(res.data);
let text = String.fromCharCode.apply(null, uint8Array);
text = decodeURIComponent(escape(text));
// 将后台通过streaming response返回的消息拼接到消息中
messages.value[messages.value.length - 1].content += text;
})
}
后端返回的数据,在小程序端展示后结果如下:

从展示效果看,返回的数据都以"data:"开头,而且数据都发生了换行。经过查询资料,了解到SSE返回的数据以"data:"开头,"\n\n"进行结尾,比如上面返回的数据类似这样的格式:
javascript
data:你好\n\n
SSE客户端端打印返回的数据:
javascript
requestTask.onChunkReceived((res) => {
console.log('响应数据:', res.data)
const uint8Array = new Uint8Array(res.data);
let text = String.fromCharCode.apply(null, uint8Array);
text = decodeURIComponent(escape(text));
// 将后台通过streaming response返回的消息拼接到消息中
messages.value[messages.value.length - 1].content += text;
})
打印内容如下:

其中,"100 97 116 97 58"表示"data:","10 10"表示"\n\n",而且根据响应数据,我们发现SSE客户端是一次处理一批后端响应的数据。
于是修改客户端解析数据的逻辑为:
javascript
requestTask.onChunkReceived((res) => {
console.log('响应数据:', res.data)
const uint8Array = new Uint8Array(res.data);
let text = String.fromCharCode.apply(null, uint8Array);
text = decodeURIComponent(escape(text));
console.log('处理前:', text);
let info = text.replace(/data:|\n\n/g, '')
console.log('处理后:', info)
// 将后台通过streaming response返回的消息拼接到消息中
messages.value[messages.value.length - 1].content += info;
})
其中通过正则表达式替换所有的"data:"和"\n\n"。替换后,展示效果如下:

但是根据后端打印的信息,在"回答:"后面是有换行的,后端输出内容:

这是由于后端返回大模型响应的数据时,需要换行的数据中间也使用了"\n\n",这就和SSE的数据格式产生了冲突。于是我们修改后端返回数据的代码,将"\n\n"替换为"\n":

前后端处理完成后,最终格式如下:
