这里写目录标题
一、EventSourcePolyfill二、直接上代码
EventSource 接口是 web 内容与服务器发送事件通信的接口。
一个 EventSource 实例会对 HTTP 服务器开启一个持久化的连接,以 text/event-stream 格式发送事件,此连接会一直保持开启直到通过调用 EventSource.close() 关闭。
EventSource 服务器发送事件是单向的。数据消息只能从服务端发送到客户端。
一、EventSourcePolyfill
EventSourcePolyfill 是EventSource封装的一个方法,EventSourcePolyfill 可以配置请求头
// 安装 npm install event-source-polyfill --save//引用import { EventSourcePolyfill } from "event-source-polyfill";
二、直接上代码
sendRequest(messageId, content, questionId, questionType) { const innerIndex = this.messageList.length - 1; const aiToken = JSON.parse(localStorage.getItem('token')); let that = this; let eventSource; if (questionId) { eventSource = new EventSourcePolyfill( `${ process.env.VUE_APP_WEB_API }/url...........?f_rnd=${new Date().getTime()}&message_id=${messageId}&question_id=${questionId}&stream=true`, { headers: { 'Content-Type': 'text/event-stream', aiToken: aiToken, accept: '*/*', 'Cache-Control': 'no-cache', Connection: 'keep-alive', // 'cache-control': 'max-age=0', }, } ); } else { eventSource = new EventSourcePolyfill( `${ process.env.VUE_APP_WEB_API }/ai_assistant_chatdoc/receive_message?f_rnd=${new Date().getTime()}&message_id=${messageId}&stream=true`, { headers: { 'Content-Type': 'text/event-stream', aiToken: aiToken, accept: '*/*', 'Cache-Control': 'no-cache', Connection: 'keep-alive', }, } ); } //open:订阅成功(和后端连接成功) eventSource.onopen = function (e) { console.log(e, '连接刚打开时触发'); }; //message:后端返回信息,格式可以和后端协商 that.messageQueue = []; //整个流式数据 this.processing = false; //判断是否返回数据中 let resultWord = ''; let rowData = {}; eventSource.onmessage = function (e) { const data = JSON.parse(e.data) || {}; //这里后端返回的是字符串所以目前我这边有转换 console.log(data, data.data.content, Date.now()); if (data.code === 200) { that.loading = false; that.scrollFlag = false; if (data.data.content === '[DONE]') { //流式结束了 rowData = data.data; } that.messageQueue.push(data.data.content); if (that.processing) return; that.processing = true; (async function processMessages() { while (that.processing) { // 改为无限循环 let message; if (that.messageQueue.length > 0) { message = that.messageQueue.shift(); if (message === '[DONE]') { that.receiveMsg.source = rowData.source; that.receiveMsg.sourceEdit = rowData.is_edit; that.$set(that.messageList[innerIndex], 'message_id', rowData.message_id); that.requestRecomme(messageId, innerIndex); } else { resultWord += message; console.log(resultWord, 'resultWord'); that.$set(that.messageList, innerIndex, { type: 'right', session_id: data.data.session_id, message_id: data.data.message_id, reply_id: data.data.reply_id, message: resultWord, source: [], sourceEdit: [], question: [], }); that.receiveMsg = that.messageList[innerIndex]; that.chcekScroll(); that.executeScroll(!that.scrollFlag); } await new Promise(resolve => setTimeout(resolve, 30)); //30毫秒读取一下message } else { that.processing = false; await new Promise(resolve => setTimeout(resolve, 800)); //如果读取速度大于流式返回速度就等一下 } if (that.messageQueue.length === 0 && message === '[DONE]') { break; } } that.processing = false; })(); } }; // error:错误(可能是断开,可能是后端返回的信息) eventSource.onerror = function (e) { console.log(e, '连接无法打开时触发'); eventSource.close(); // 关闭连接 setTimeout(() => {}, 5000); }; },
链接: https://blog.csdn.net/weixin_49066399/article/details/138713416