云计算百科
云计算领域专业知识百科平台

Uniapp 中使用 EventSource 实现服务器推送功能(SSE),实现对接ChatGPT,进行流式输出。

在 Uniapp 中,如果需要实现服务器推送功能(Server-Sent Events, SSE),可以使用 EventSource。然而,在 App 端,EventSource 并不被原生支持,因此需要使用 EventSourcePolyfill 来实现跨平台兼容。

1. 什么是 SSE?

SSE(Server-Sent Events)是一种服务器向客户端推送实时数据的技术。与 WebSocket 不同,SSE 是单向的,服务器可以主动向客户端推送数据,而客户端只能接收数据。


​2. 实现步骤
​2.1 安装依赖

首先,安装 EventSourcePolyfill 和 axios:

npm install event-source-polyfill
npm install axios

​2.2 使用 renderjs 实现跨平台兼容

由于 App 端不支持原生的 EventSource,需要使用 renderjs 来实现跨平台兼容。

​代码实现

<script module="renderScript" lang="renderjs">
import { EventSourcePolyfill } from 'event-source-polyfill';

export default {
data() {
return {
IsSupportSse: 'EventSource' in window,
};
},
mounted() {
window.addEventListener('beforeunload', () => {
this.source.close(); // 页面关闭时关闭连接
});
this.sse(); // 初始化 SSE 连接
},
methods: {
// 发送数据到 service 层
emitData() {
// #ifdef APP
UniViewJSBridge.publishHandler('onWxsInvokeCallMethod', {
cid: this._$id,
method: 'acceptDataFromRenderjs',
args: {
type: this.messageData,
},
});
// #endif
setTimeout(() => {
this.$ownerInstance.callMethod('acceptDataFromRenderjs', {
type: this.messageData,
});
}, 200);
},
// 初始化 SSE 连接
sse() {
if ('EventSource' in window) {
console.log('SSE 连接中…');
this.source = new EventSourcePolyfill(
`http://140.143.171.167:8080/api/common/sse/createConnect?clientId=${plus.storage.getItem('token')}`,
{
headers: {
token: plus.storage.getItem('token'),
'Content-Type': 'application/x-www-form-urlencoded',
},
heartbeatTimeout: 10 * 60 * 1000, // 重连时间间隔
}
);
this.source.onmessage = (e) => {
this.messageData = e.data; // 接收服务器推送的数据
this.emitData(); // 发送数据到 service 层
};
this.source.onopen = () => {
console.log('—连接打开—');
};
this.source.onerror = (e) => {
if (e.readyState === EventSource.CLOSED) {
console.log('—连接关闭—');
} else {
console.log('onerror:', e.readyState);
}
};
} else {
console.log('当前环境不支持 SSE');
}
},
},
};
</script>

​2.3 在 script 层接收数据

在 script 层中,通过 acceptDataFromRenderjs 方法接收 renderjs 层传递的数据,并处理显示。

export default {
data() {
return {
curStreamMsgObj: null, // 当前接收到的数据
};
},
methods: {
async acceptDataFromRenderjs(options) {
// 控制页面向下滚动到底部
uni.pageScrollTo({
scrollTop: 99999999999999999,
duration: 0,
});

if (this.curStreamMsgObj) {
// 正常接收数据,追加显示到前端
this.curStreamMsgObj.content += JSON.parse(options.type);
} else {
// 第一次接收数据
this.curStreamMsgObj = {
role: 'gpt',
content: JSON.parse(options.type),
};
this.gpt.push(this.curStreamMsgObj); // 添加到消息列表
await this.$nextTick();
}
console.log('接收 renderjs 发回的数据:', JSON.parse(options.type));
},
},
};


​3. 注意事项
  • ​跨平台兼容性

    • 在 App 端,必须使用 renderjs 和 EventSourcePolyfill 来实现 SSE 功能。
  • ​性能优化

    • 避免频繁创建和关闭 SSE 连接,合理设置 heartbeatTimeout。
  • ​数据格式

    • 确保服务器返回的数据格式与前端处理逻辑一致。
  • uniapp怎么使用EventSourcePolyfill  

    参考链接:uniapp怎么使用EventSourcePolyfill – DCloud问答

    renderjs内如何主动发起通讯? :renderjs内如何主动发起通讯? – DCloud问答

    SSE(Server-Sent Events)请求之EventSource :

    SSE(Server-Sent Events)请求之EventSource_sse请求-CSDN博客

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Uniapp 中使用 EventSource 实现服务器推送功能(SSE),实现对接ChatGPT,进行流式输出。
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!