# WebSocket

下面是一个简单的WS的封装类,

class HeartbeatWebSocket {
  constructor(url, protocols = "") {
    this.url = url;
    this.protocols = protocols;
    this.ws = null;
    this.reconnectInterval = 1000; // 重连间隔时间
    this.heartbeatInterval = 30000; // 心跳间隔时间
    this.heartbeatTimeout = 60000; // 心跳超时时间 10000
    this.heartbeatTimer = null; // 心跳定时器
    this.heartbeatTimeoutTimer = null; // 心跳超时定时器
    this.reconnectTimer = null; // 重连定时器
    this.isConnected = false; // 连接状态
    this.reconnectCount = 1; // 重连次数 
    this.reconnectMaxCount = 10; // 最大重连次数

    this.connect();
  }

  async connect() {
    this.ws = new WebSocket(this.url);
    /* 
    {
      headers: {
        Authorization: "Bearer " + getToken(),
      },
    }
*/

    this.ws.addEventListener("open", (event) => {
      console.log("WebSocket连接成功", event);
      this.ws.send("Authorization: Bearer " + getToken());
      this.isConnected = true;
      setTimeout(() => {
        this.startHeartbeat();
      }, 10000);
      this.onopen && this.onopen();
    });

    /* this.ws.onopen = () => {
      console.log("WebSocket连接成功");
      this.isConnected = true;
      this.startHeartbeat();
      this.onopen && this.onopen();
    }; */

    this.ws.onmessage = (event) => {
      // 收到消息,处理心跳响应
      if (event.data === "pong") {
        this.resetHeartbeat();
      }
      this.onmessage && this.onmessage(event);
    };

    this.ws.onclose = () => {
      console.log("WebSocket连接关闭");
      this.isConnected = false;
      this.stopHeartbeat();
      // this.reconnect();
      this.onclose && this.onclose();
    };

    this.ws.onerror = (error) => {
      console.error("WebSocket发生错误:", error);
      this.isConnected = false;
      this.onerror && this.onerror(error);
    };
  }

  send(data) {
    if (this.ws && this.isConnected) {
      this.ws.send(data);
    }
  }

  startHeartbeat() {
    this.heartbeatTimer = setInterval(() => {
      this.send("ping");
      console.debug("发送心跳ping");
      // 发送心跳后,设置一个超时定时器,如果超时未收到响应则关闭连接并重连
      this.heartbeatTimeoutTimer = setTimeout(() => {
        console.warn("心跳响应超时,关闭连接");
        this.ws.close();
      }, this.heartbeatTimeout);
    }, this.heartbeatInterval);
  }

  resetHeartbeat() {
    // 收到心跳响应,清除超时定时器
    clearTimeout(this.heartbeatTimeoutTimer);
  }

  stopHeartbeat() {
    clearInterval(this.heartbeatTimer);
    clearTimeout(this.heartbeatTimeoutTimer);
  }

  reconnect() {
    // 避免重复重连
    if (this.reconnectTimer) {
      return;
    }
    if (this.reconnectCount >= this.reconnectMaxCount) {
      return;
    }
    this.reconnectTimer = setTimeout(() => {
      console.log("尝试重连...");
      this.connect();
      this.reconnectTimer = null;
      this.reconnectCount++;
    }, this.reconnectInterval);
  }

  close() {
    this.stopHeartbeat();
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
    if (this.ws) {
      this.ws.close();
    }
  }

  // 可选的钩子函数,由外部设置
  onopen() {}
  onmessage(event) {}
  onclose() {}
  onerror(error) {}
}

export default HeartbeatWebSocket;

// 使用示例
/* 
const ws = new HeartbeatWebSocket("wss://echo.websocket.org");

ws.onopen = () => {
  console.log("连接打开");
};

ws.onmessage = (event) => {
  console.log("收到消息:", event.data);
};

ws.onclose = () => {
  console.log("连接关闭");
};

ws.onerror = (error) => {
  console.error("错误:", error);
};

// 发送消息
ws.send("Hello WebSocket!");

 */
// 在不需要时,可以手动关闭连接
// ws.close();

上次更新: 11/24/2025, 8:43:18 AM