class类封装ws

export interface WebsocketProps {
  url: string; // WebSocket 连接地址
  reconnectInterval?: number; // 重连间隔时间(毫秒)
  heartBeatInterval?: number; // 心跳间隔时间(毫秒)
  isHeartbeatEnabled?: boolean; // 是否开启心跳
  heartMessage?: string; // 心跳消息
  maxReconnectAttempts?: number; // 最大重连次数
}

export default class Websocket {
  url: string;
  reconnectInterval: number;
  heartBeatInterval: number;
  isHeartbeatEnabled: boolean;
  heartMessage: string;
  maxReconnectAttempts: number;
  private reconnectAttempts: number; // 当前重连尝试次数
  private ws: WebSocket | null; // WebSocket 对象
  private heartBeatTimer: NodeJS.Timeout | null; // 心跳定时器
  private reconnectTimer: NodeJS.Timeout | null; // 重连定时器
  callback: Function;

  constructor(
    {
      url,
      reconnectInterval = 5000, // 默认5秒
      heartBeatInterval = 10000, // 默认10秒
      isHeartbeatEnabled = true,
      heartMessage = "hello",
      maxReconnectAttempts = 5, // 默认5次
    }: WebsocketProps,
    callback: Function
  ) {
    this.url = url;
    this.reconnectInterval = reconnectInterval;
    this.heartBeatInterval = heartBeatInterval;
    this.isHeartbeatEnabled = isHeartbeatEnabled;
    this.heartMessage = heartMessage;
    this.maxReconnectAttempts = maxReconnectAttempts;
    this.reconnectAttempts = 0;
    this.ws = null;
    this.heartBeatTimer = null;
    this.reconnectTimer = null;
    this.connectWs();
    this.callback = callback;
  }

  // 连接 Websocket
  private connectWs() {
    this.closeWs();
    this.stopReconnectWs();
    this.stopHeartBeat();

    // 创建 WebSocket 对象
    this.ws = new WebSocket(this.url);

    // 打开
    this.ws.onopen = () => {
      this.reconnectAttempts = 0;
      this.isHeartbeatEnabled && this.startHeartBeat();
      this.callback("open", "连接成功");
    };

    // 消息
    this.ws.onmessage = (event: { data: string }) => {
      this.callback("message", event.data);
    };

    // 关闭
    this.ws.onclose = () => {
      this.stopHeartBeat();
      if (this.reconnectAttempts <= this.maxReconnectAttempts) {
        this.reconnectTimer = setTimeout(() => {
          this.reconnectAttempts++;
          this.callback("close", `第 ${this.reconnectAttempts} 次尝试重连`);
          this.connectWs();
        }, this.reconnectInterval);
      } else {
        this.stopReconnectWs();
        this.callback("close", `已达到最大重连次数,停止重连`);
      }
    };
  }

  // 发送消息
  public sendMessage(message: string) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(message);
    }
  }

  // 开启心跳
  private startHeartBeat = () => {
    this.heartBeatTimer = setInterval(() => {
      if (this.ws?.readyState === WebSocket.OPEN) {
        this.ws.send(this.heartMessage);
      }
    }, this.heartBeatInterval);
  };

  // 停止心跳
  private stopHeartBeat = () => {
    if (this.heartBeatTimer) {
      clearInterval(this.heartBeatTimer);
      this.heartBeatTimer = null;
    }
  };

  // 停止重连
  private stopReconnectWs = () => {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
  };

  // 关闭连接
  public closeWs = () => {
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
  };
}

// 调用示例
const initWebsocket = () => {
  const ws = new Websocket(
    { url: "ws://127.0.0.1" },
    async (type: string, message: string) => {
      console.log(type);
      console.log(message);
    }
  );
  console.log(ws);
};

initWebsocket();

posted @ 2024-06-05 14:55  wanglei1900  阅读(9)  评论(0编辑  收藏  举报