10.10综合交易所原始源码-管理后台
1
admin
2026-01-06 089bf5d2378b3c4a61d795b2a92bede2c193b771
src/plugins/ws-socket.js
New file
@@ -0,0 +1,242 @@
class WsSocket {
  /**
   * Websocket 连接
   *
   * @var Websocket
   */
  connect = null
  /**
   * 配置信息
   *
   * @var Object
   */
  config = {
    heartbeat: {
      setInterval: null,
      pingInterval: 20000,
      pingTimeout: 60000,
    },
    reconnect: {
      lockReconnect: false,
      setTimeout: null, // 计时器对象
      time: 5000, // 重连间隔时间
      number: 1000, // 重连次数
    },
  }
  // 最后心跳时间
  lastTime = 0
  /**
   * 自定义绑定消息事件
   *
   * @var Array
   */
  onCallBacks = []
  defaultEvent = {
    onError: evt => {},
    onOpen: evt => {},
    onClose: evt => {},
  }
  /**
   * 创建 WsSocket 的实例
   *
   * @param {Function} urlCallBack url闭包函数
   * @param {Object} events 原生 WebSocket 绑定事件
   */
  constructor(urlCallBack, events) {
    this.urlCallBack = urlCallBack
    // 定义 WebSocket 原生方法
    this.events = Object.assign({}, this.defaultEvent, events)
    this.on('connect', data => {
      this.config.heartbeat.pingInterval = data.ping_interval * 1000
      this.config.heartbeat.pingTimeout = data.ping_timeout * 1000
      this.heartbeat()
    })
  }
  /**
   * 事件绑定
   *
   * @param {String} event 事件名
   * @param {Function} callBack 回调方法
   */
  on(event, callBack) {
    this.onCallBacks[event] = callBack
    return this
  }
  /**
   * 加载 WebSocket
   */
  loadSocket() {
    const url = this.urlCallBack()
    const connect = new WebSocket(url)
    connect.onerror = this.onError.bind(this)
    connect.onopen = this.onOpen.bind(this)
    connect.onmessage = this.onMessage.bind(this)
    connect.onclose = this.onClose.bind(this)
    this.connect = connect
  }
  /**
   * 连接 Websocket
   */
  connection() {
    this.connect == null && this.loadSocket()
  }
  /**
   * 掉线重连 Websocket
   */
  reconnect() {
    // 没连接上会一直重连,设置延迟避免请求过多
    clearTimeout(this.config.reconnect.setTimeout)
    this.config.reconnect.setTimeout = setTimeout(() => {
      this.connection()
      console.log(`网络连接已断开,正在尝试重新连接...`)
    }, this.config.reconnect.time)
  }
  /**
   * 解析接受的消息
   *
   * @param {Object} evt Websocket 消息
   */
  onParse(evt) {
    const { event, content } = JSON.parse(evt.data)
    return {
      event: event,
      data: content,
      orginData: evt.data,
    }
  }
  /**
   * 打开连接
   *
   * @param {Object} evt Websocket 消息
   */
  onOpen(evt) {
    this.lastTime = new Date().getTime()
    this.events.onOpen(evt)
    this.ping()
  }
  /**
   * 关闭连接
   *
   * @param {Object} evt Websocket 消息
   */
  onClose(evt) {
    this.events.onClose(evt)
    this.connect.close()
    this.connect = null
    evt.code == 1006 && this.reconnect()
  }
  /**
   * 连接错误
   *
   * @param {Object} evt Websocket 消息
   */
  onError(evt) {
    this.events.onError(evt)
    this.connect.close()
    this.connect = null
    this.reconnect()
  }
  /**
   * 接收消息
   *
   * @param {Object} evt Websocket 消息
   */
  onMessage(evt) {
    this.lastTime = new Date().getTime()
    let result = this.onParse(evt)
    // 判断消息事件是否被绑定
    if (this.onCallBacks.hasOwnProperty(result.event)) {
      this.onCallBacks[result.event](result.data, result.orginData)
    } else {
      console.warn(`WsSocket 消息事件[${result.event}]未绑定...`)
    }
  }
  /**
   * WebSocket 心跳检测
   */
  heartbeat() {
    this.config.heartbeat.setInterval = setInterval(() => {
      let t = new Date().getTime()
      if (t - this.lastTime > this.config.heartbeat.pingTimeout) {
        if(this.connect){
          this.connect.close()
        }
        this.reconnect()
      } else {
        this.ping()
      }
    }, this.config.heartbeat.pingInterval)
  }
  ping() {
    this.connect.send('{"event":"heartbeat","content":"ping"}')
  }
  /**
   * 聊天发送数据
   *
   * @param {Object} mesage
   */
  send(mesage) {
    this.connect.send(JSON.stringify(mesage))
  }
  /**
   * 关闭连接
   */
  close() {
    this.connect.close()
  }
  /**
   * 推送消息
   *
   * @param {String} event 事件名
   * @param {Object} data 数据
   */
  emit(event, data) {
    const content = JSON.stringify({ event, data })
    if (this.connect && this.connect.readyState === 1) {
      this.connect.send(content)
    } else {
      alert('WebSocket 连接已关闭...')
      console.error('WebSocket 连接已关闭...', this.connect)
    }
  }
}
export default WsSocket