前端怎么用 EventSource并配置请求头及加参数(流式数据)

程序媛_MISS_zhang_0110 2024-10-06 16:33:01 阅读 70

这里写目录标题

一、EventSourcePolyfill二、直接上代码

EventSource 接口是 web 内容与服务器发送事件通信的接口。

一个 EventSource 实例会对 HTTP 服务器开启一个持久化的连接,以 text/event-stream 格式发送事件,此连接会一直保持开启直到通过调用 EventSource.close() 关闭。

EventSource 服务器发送事件是单向的。数据消息只能从服务端发送到客户端。

一、EventSourcePolyfill

EventSourcePolyfill 是EventSource封装的一个方法,EventSourcePolyfill 可以配置请求头

<code>// 安装

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



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。