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

2023-06-29  本文已影响0人  有一个程序媛
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
上一篇 下一篇

猜你喜欢

热点阅读