您现在的位置是:首页 >技术交流 >websocket封装【心跳、断连问题处理】网站首页技术交流

websocket封装【心跳、断连问题处理】

小P孩zzh 2025-08-04 00:01:03
简介websocket封装【心跳、断连问题处理】

创建mixins.js
需要注意问题:

  1. WebSocket 连接可能会因为多种原因断开,如网络问题、服务器重启或客户端关闭等
  2. 关于问题数据上报:目前采用神策上报
  3. 每次退出页面都需要关闭websocket和清除定时器
export const WebSocketClient = {
  data() {
    return {
      url: "", // websocket地址
      WebSocket: null, // websocket实例
      reconnectAttempts: 0, // 重连次数
      maxReconnectAttempts: 5, // 最大重连次数
      reconnectInterval: 1000, // 重连间隔
      heartbeatInterval: 1000 * 30, // 发送心跳数据间隔
      heartbeatTimer: null, // 心跳定时器
      stopWebSocket: false, // 是否停止websocket
    };
  },

  mounted() {},

  methods: {
    // 初始化连接
    connect() {
      if (this.reconnectAttempts === 0) {
        console.log("WebSocket", `初始化连接中...`);
      }
      if (this.WebSocket) {
        return;
      }
      // this.url = "ws://127.0.0.1:8080";
      this.WebSocket = new WebSocket(this.url);
      // websocket连接成功
      this.WebSocket.onopen = (event) => {
        this.stopWebSocket = false;
        // 重置重连尝试成功连接
        this.reconnectAttempts = 0;
        // 在连接成功时停止当前的心跳检测并重新启动
        this.startHeartbeat();
        console.log("连接成功,等待服务端数据推送[onopen]...");
      };

      this.WebSocket.onmessage = (event) => {
        // 此处的【message】方法还未写,具体项目具体需求具体分析
        this.handleEvent("message", event);
        this.startHeartbeat();
      };

      this.WebSocket.onclose = (event) => {
        if (this.reconnectAttempts == 0) {
          console.log("连接断开[onclose]...");
        }
        if (!this.stopWebSocket) {
          this.handleReconnect();
        }
        this.handleEvent("close", event);
      };

      this.WebSocket.onerror = (event) => {
        if (this.reconnectAttempts === 0) {
          console.log("连接异常[onerror]...");
        }
        this.closeHeartbeat();
        // 此处的【error】方法还未写,具体项目具体需求具体分析
        this.handleEvent("error", event);
      };
    },

    // 断网重连
    handleReconnect() {
      if (this.reconnectAttempts < this.maxReconnectAttempts) {
        this.reconnectAttempts++;
        console.log("WebSocket,尝试重连...");
        setTimeout(() => {
          this.connect();
        }, this.reconnectInterval);
      } else {
        this.closeHeartbeat();
        console.log(`最大重连失败,终止重连: ${this.url}`);
      }
    },

    // 关闭连接
    close() {
      if (this.WebSocket) {
        this.stopWebSocket = true;
        this.WebSocket.close();
        this.WebSocket = null;
      }
      this.closeHeartbeat();
    },

    // 开始心跳检测 --> 定时发送心跳消息
    startHeartbeat() {
      if (this.stopWebSocket) return;
      if (this.heartbeatTimer) {
        this.closeHeartbeat();
      }
      this.heartbeatTimer = setInterval(() => {
        if (this.WebSocket) {
          this.WebSocket.send(JSON.stringify({ type: "heartBeat", data: {} }));
          console.log("WebSocket", "送心跳数据...");
        } else {
          console.error("[WebSocket] 未连接");
        }
      }, this.heartbeatInterval);
    },

    // 关闭心跳
    closeHeartbeat() {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    },

    // 监听事件
    handleEvent(type, data) {
      // 进行有对应的事件监听,则调用对应的事件监听函数
      // type==close时,则是关闭
      this.[type]();
      console.log("type", type);
      console.log("data", data);
    },
  },
};


// 注意: 当用户退出页面时,记得清除定时器和关闭websocket连接

希望有更好建议和想法的小伙伴们能在评论区完善

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。