eventsource处理的流渲染到页面方法封装

import { EventSourcePolyfill } from 'event-source-polyfill'
let connectEventTimeout = 60000 * 5
let ev = null as any
let connectEventTimer = null as any
let waitMsgTimer = null as any
const requestEv = () => {
  const getEvFlow= (params: any, callback: any) => {
    let data = ''
    // 接口可作为参数传递进来
    ev = new EventSourcePolyfill(params.fullUrl || (params.url), {
      headers: {
        token: '123' // 携带参数
      },
      heartbeatTimeout: connectEventTimeout  // 心跳超时时长,也可传参
    })
    connectEventTimer= setTimeout(() => {
      ev?.close()
      connectEventTimer = null
      clearTimeout(connectEventTimer )
    }, connectEventTimeout )
    ev.onopen = (e: any) => {
      connectEventTimer = null
      clearTimeout(connectEventTimer )
    }
    ev.onmessage = (e: any) => {
      // e中有个status属性是用来记录当前流的状态,可捕获到流是正在输出还是输出结束等
      clearTimeout(waitMsgTimer)
      let txt = e.data
      data += txt
      data = data.replace('[ERROR]', '').replace('[ILLEGAL]', '').replace('[END]', '')
      callback.doingCallback?.(data)
      if (txt === '[ERROR]') { // gpt异常处理会返回[ERROR]
        callback.errCallback?.(data.replace('[ERROR]', ''))
        ev?.close()
        return
      } else if (txt === '[ILLEGAL]') { // gpt违法处理会返回[ILLEGAL]
        callback.illegalCallback?.(data.replace('[ILLEGAL]', ''))
        ev?.close()
        return
      } else if (txt === '[EV_END]') { // gpt结束处理会返回[EV_END]
        callback.endCallback?.(data.replace('[EV_END]', '')) // 吐出去的回调函数
        ev?.close()
        return
      }
      // 10秒长时间没反应的时候自动停止流的状态(此处还有一个未解决的问题就是如果手动停止流的输出会跟10秒后的停止流函数重合)
      waitMsgTimer = setTimeout(() => {
        callback.endCallback?.(data.replace('[ERROR]', ''))
        ev?.close()
      }, 10000)
    }
    ev.onerror = (e: any) => {
      ev?.close()
      connectEventTimer= null
      callback.evErrCallback?.(e)
      clearTimeout(connectEventTimer)
    }
    ev.onclose = (e: any) => {
      console.log(e, 'renderEvFlow onclose')
    }
    ev.addEventListener('close', (e: any) => {
      console.log(e, 'renderEvFlow close')
    })
  }

  const stopFlow = () => {
    ev?.close()
    connectEventTimer= null
    clearTimeout(connectEventTimer)
  }
  return { getEvFlow, stopFlow }
}
export default requestEv
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容