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

打印 上一主题 下一主题

主题 902|帖子 902|积分 2706

EventSource 接口是 web 内容与服务器发送事件通讯的接口。
一个 EventSource 实例会对 HTTP 服务器开启一个持久化的连接,以 text/event-stream 格式发送事件,此连接会不停保持开启直到通过调用 EventSource.close() 关闭。
EventSource 服务器发送事件是单向的。数据消息只能从服务端发送到客户端。
  一、EventSourcePolyfill

   EventSourcePolyfill 是EventSource封装的一个方法,EventSourcePolyfill 可以配置请求头
  1. // 安装
  2. npm install event-source-polyfill --save
  3. //引用
  4. import { EventSourcePolyfill } from "event-source-polyfill";
复制代码
二、直接上代码

  1. sendRequest(messageId, content, questionId, questionType) {
  2.       const innerIndex = this.messageList.length - 1;
  3.       const aiToken = JSON.parse(localStorage.getItem('token'));
  4.       let that = this;
  5.       let eventSource;
  6.       if (questionId) {
  7.         eventSource = new EventSourcePolyfill(
  8.           `${
  9.             process.env.VUE_APP_WEB_API
  10.           }/url...........?f_rnd=${new Date().getTime()}&message_id=${messageId}&question_id=${questionId}&stream=true`,
  11.           {
  12.             headers: {
  13.               'Content-Type': 'text/event-stream',
  14.               aiToken: aiToken,
  15.               accept: '*/*',
  16.               'Cache-Control': 'no-cache',
  17.               Connection: 'keep-alive',
  18.               // 'cache-control': 'max-age=0',
  19.             },
  20.           }
  21.         );
  22.       } else {
  23.         eventSource = new EventSourcePolyfill(
  24.           `${
  25.             process.env.VUE_APP_WEB_API
  26.           }/ai_assistant_chatdoc/receive_message?f_rnd=${new Date().getTime()}&message_id=${messageId}&stream=true`,
  27.           {
  28.             headers: {
  29.               'Content-Type': 'text/event-stream',
  30.               aiToken: aiToken,
  31.               accept: '*/*',
  32.               'Cache-Control': 'no-cache',
  33.               Connection: 'keep-alive',
  34.             },
  35.           }
  36.         );
  37.       }
  38.       //open:订阅成功(和后端连接成功)
  39.       eventSource.onopen = function (e) {
  40.         console.log(e, '连接刚打开时触发');
  41.       };
  42.       //message:后端返回信息,格式可以和后端协商
  43.       that.messageQueue = []; //整个流式数据
  44.       this.processing = false; //判断是否返回数据中
  45.       let resultWord = '';
  46.       let rowData = {};
  47.       eventSource.onmessage = function (e) {
  48.         const data = JSON.parse(e.data) || {}; //这里后端返回的是字符串所以目前我这边有转换
  49.         console.log(data, data.data.content, Date.now());
  50.         if (data.code === 200) {
  51.           that.loading = false;
  52.           that.scrollFlag = false;
  53.           if (data.data.content === '[DONE]') { //流式结束了
  54.             rowData = data.data;
  55.           }
  56.           that.messageQueue.push(data.data.content);
  57.           if (that.processing) return;
  58.           that.processing = true;
  59.           (async function processMessages() {
  60.             while (that.processing) {
  61.               // 改为无限循环
  62.               let message;
  63.               if (that.messageQueue.length > 0) {
  64.                 message = that.messageQueue.shift();
  65.                 if (message === '[DONE]') {
  66.                   that.receiveMsg.source = rowData.source;
  67.                   that.receiveMsg.sourceEdit = rowData.is_edit;
  68.                   that.$set(that.messageList[innerIndex], 'message_id', rowData.message_id);
  69.                   that.requestRecomme(messageId, innerIndex);
  70.                 } else {
  71.                   resultWord += message;
  72.                   console.log(resultWord, 'resultWord');
  73.                   that.$set(that.messageList, innerIndex, {
  74.                     type: 'right',
  75.                     session_id: data.data.session_id,
  76.                     message_id: data.data.message_id,
  77.                     reply_id: data.data.reply_id,
  78.                     message: resultWord,
  79.                     source: [],
  80.                     sourceEdit: [],
  81.                     question: [],
  82.                   });
  83.                   that.receiveMsg = that.messageList[innerIndex];
  84.                   that.chcekScroll();
  85.                   that.executeScroll(!that.scrollFlag);
  86.                 }
  87.                 await new Promise(resolve => setTimeout(resolve, 30)); //30毫秒读取一下message
  88.               } else {
  89.                 that.processing = false;
  90.                 await new Promise(resolve => setTimeout(resolve, 800)); //如果读取速度大于流式返回速度就等一下
  91.               }
  92.               if (that.messageQueue.length === 0 && message === '[DONE]') {
  93.                 break;
  94.               }
  95.             }
  96.             that.processing = false;
  97.           })();
  98.         }
  99.       };
  100.       //  error:错误(可能是断开,可能是后端返回的信息)
  101.       eventSource.onerror = function (e) {
  102.         console.log(e, '连接无法打开时触发');
  103.         eventSource.close(); // 关闭连接
  104.         setTimeout(() => {}, 5000);
  105.       };
  106.     },
复制代码
链接: https://blog.csdn.net/weixin_49066399/article/details/138713416

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

傲渊山岳

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表