src/socket/index.js
@@ -1,134 +1,20 @@
import eventBus from './eventBus.js';
import { messageTypes } from '@/enum/socketMessage.js';
import { encodeMessage, decodeMessage } from './socketMessage.js';
import { $socket_base_url } from '@/api/index.js';
class FYWebSocket extends WebSocket {
  constructor() {
    super($socket_base_url);
    return this;
  }
  /**
   * heartBeatConfig 心跳连接参数
   *    time: 心跳时间间隔
   *    timeout: 心跳超时间隔
   *    reconnect: 断线重连时间间隔
   * isReconnect 是否断线重连
   */
  init(heartBeatConfig, isReconnect) {
    this.onopen = this.openHandler; // 连接成功后的回调函数
    this.onclose = this.closeHandler; // 连接关闭后的回调 函数
    this.onmessage = this.messageHandler; // 收到服务器数据后的回调函数
    this.onerror = this.errorHandler; // 连接发生错误的回调方法
    this.heartBeatConfig = heartBeatConfig; // 心跳连接配置参数
    this.isReconnect = isReconnect; // 记录是否断线重连
    this.reconnectTimer = null; // 记录断线重连的时间器
    this.startHeartBeatTimer = null; // 记录心跳时间器
    this.webSocketState = false; // 记录socket连接状态 true为已连接
  }
  // 获取消息
  getMessage({ data }) {
    return decodeMessage(data);
  }
  // 发送消息
  sendMessage(type, data) {
    return this.send(encodeMessage(type, data));
  }
  // 连接成功后的回调函数
  openHandler() {
    console.log('====onopen 连接成功====');
    // socket状态设置为连接,做为后面的断线重连的拦截器
    this.webSocketState = true;
    // 判断是否启动心跳机制
    if (this.heartBeatConfig && this.heartBeatConfig.time) {
      this.startHeartBeat(this.heartBeatConfig.time);
    }
  }
  // 收到服务器数据后的回调函数
  messageHandler(res) {
    const webSocketMsg = this.getMessage(res);
    if (!(webSocketMsg && webSocketMsg != null && webSocketMsg != {})) {
      return;
    }
    const type = webSocketMsg.type;
    const data = webSocketMsg.data
    switch (type) {
      case '1': // 后台任务
        // 发送事件
        eventBus.emit('1', data);
        console.log('====onmessage 后台任务====', data);
        break;
      case '2': // 业务日志
        // 发送事件
        eventBus.emit('2', data);
        console.log('====onmessage 业务日志====', data);
        break;
      case '0': // 心跳检测
        // 将连接状态更新为在线
        this.webSocketState = true;
        eventBus.emit('0', data);
        console.log('====onmessage 心跳检测====', data);
        break;
    }
  }
  // 连接关闭后的回调 函数
  closeHandler() {
    console.log('====onclose websocket关闭连接====');
    // 设置socket状态为断线
    this.webSocketState = false;
    // 在断开连接时 清除心跳时间器和 断开重连时间器
    this.startHeartBeatTimer && clearTimeout(this.startHeartBeatTimer);
    this.reconnectTimer && clearTimeout(this.reconnectTimer);
    this.reconnectWebSocket();
  }
  errorHandler() {
    console.log('====onerror websocket连接出错====');
    // 设置socket状态为断线
    this.webSocketState = false;
    // 重新连接
    this.reconnectWebSocket();
  }
import { FYWebSocket } from '@/socket/FYWebSocket.js';
import MessageManager from '@/socket/MessageManager.js';
  // 心跳初始化方法 time:心跳间隔
  startHeartBeat(time) {
    this.startHeartBeatTimer = setTimeout(() => {
      // 客户端每隔一段时间向服务端发送一个心跳消息
      this.sendMessage(messageTypes[0].value, Date.now());
      this.waitingServer();
    }, time);
  }
  //在客户端发送消息之后,延时等待服务器响应,通过webSocketState判断是否连线成功
  waitingServer() {
    this.webSocketState = false;
    setTimeout(() => {
      // 连线成功状态下 继续心跳检测
      if (this.webSocketState) {
        this.startHeartBeat(this.heartBeatConfig.time);
        return;
      }
      console.log('心跳无响应, 已经和服务端断线');
      // 重新连接时,记得要先关闭当前连接
      try {
        this.close();
      } catch (error) {
        console.log('当前连接已经关闭');
      }
      // // 重新连接
      // this.reconnectWebSocket()
    }, this.heartBeatConfig.timeout);
  }
let socket = null;
  // 重新连接
  reconnectWebSocket() {
    // 判断是否是重新连接状态(即被动状态断线),如果是主动断线的不需要重新连接
    if (!this.isReconnect) {
      return;
    }
    // 根据传入的断线重连时间间隔 延时连接
    this.reconnectTimer = setTimeout(() => {
      // 触发重新连接事件
      eventBus.emit('reconnect');
    }, this.heartBeatConfig.reconnect);
  }
// 连接websocket
function connectWebSocket() {
  socket = new FYWebSocket();
  socket.init(() => {
    connectWebSocket();
  }, MessageManager);
  return socket;
}
export { FYWebSocket };
/**
 * 初始化socket客户端
 */
function initSocketClient() {
  connectWebSocket();
}
export { initSocketClient };