自用基于 TypeScript 的 WebSocket 客户端封装

代码本体

typescript 复制代码
export interface IWSOptions {
  url?: string;
  sendContent?: string | object;
  token?: string;
  reconnectInterval?: number;
  heartbeatInterval?: number;
  heartbeatContent?: string | object;
  onOpen?: () => void;
  onMessage?: (data: any) => void;
  onClose?: (event: Event) => void;
  onError?: (error: Event) => void;
}

export class WebSocketClient {
  private ws: WebSocket | null = null;
  private reconnectInterval: number = 2000;
  private heartbeatInterval: number = 1000;
  private heartbeatTimer: ReturnType<typeof setInterval> | null = null;
  private reconnectTimer: ReturnType<typeof setTimeout> | null = null;

  constructor(private options: IWSOptions) {
    this.reconnectInterval =
      options.reconnectInterval ?? this.reconnectInterval;
    this.heartbeatInterval =
      options.heartbeatInterval ?? this.heartbeatInterval;
    this.init();
  }

  private init() {
    this.ws = new WebSocket(
      this.options.url ?? import.meta.env.VITE_HW_ADDRESS
    );
    this.ws.onopen = this.handleOpen;
    this.ws.onmessage = this.handleMessage;
    this.ws.onerror = this.handleError;
    this.ws.onclose = this.handleClose;
  }

  private handleOpen = (_event: Event) => {
    this.clearReconnect();
    this.sendInitMessage();
    this.startHeartbeat();
    this.options.onOpen?.();
  };

  private handleMessage = (e: MessageEvent) => {
    this.options.onMessage?.(e.data);
  };

  private handleError = (e: ErrorEvent) => {
    this.options.onError?.(e);
  };

  private handleClose = (e: CloseEvent) => {
    this.clearHeartbeat();
    this.startReconnect();
    this.options.onClose?.(e);
  };

  private sendInitMessage() {
    if (this.options.sendContent) {
      this.send(this.options.sendContent);
    }
  }

  private sendHeartbeat() {
    if (this.options.heartbeatContent) {
      this.send(this.options.heartbeatContent);
    }
  }

  private send(content: string | object) {
    const message =
      typeof content === "string" ? content : JSON.stringify(content);
    this.ws?.send(message);
  }

  private startHeartbeat() {
    if (this.heartbeatInterval > 0) {
      this.heartbeatTimer = setInterval(
        () => this.sendHeartbeat(),
        this.heartbeatInterval
      );
    }
  }

  private clearHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
  }

  private startReconnect() {
    if (this.reconnectInterval > 0) {
      this.reconnectTimer = setTimeout(() => {
        this.init();
      }, this.reconnectInterval);
    }
  }

  private clearReconnect() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
  }

  public close() {
    this.clearHeartbeat();
    this.clearReconnect();
    this.ws?.close();
    this.ws = null;
  }
}

使用例

typescript 复制代码
import { WebSocketClient } from "./websocket";

new WebSocketClient({
  sendContent: {
    message: "hello from tshihcin!",
  },
  reconnectInterval: 3000,
  heartbeatInterval: 1500,
  onMessage: (data: any) => {
    console.log(data);
  },
  onError: (e: Event) => {
    console.log(e);
  },
});
相关推荐
玄尺_00712 小时前
uniapp h5端使浏览器弹出下载框
前端·javascript·uni-app
军军君0112 小时前
Three.js基础功能学习三:纹理与光照
前端·javascript·3d·前端框架·three·三维·三维框架
淡笑沐白12 小时前
Vue3基础语法教程
前端·javascript·vue.js
可触的未来,发芽的智生12 小时前
2025年终总结:智能涌现的思考→放弃冯诺依曼架构范式,拥抱“约束产生智能”
javascript·人工智能·python·神经网络·程序人生
2501_9462447813 小时前
Flutter & OpenHarmony OA系统下拉刷新组件开发指南
开发语言·javascript·flutter
没事多睡觉66613 小时前
零基础React + TypeScript 教程
前端·react.js·typescript
_Kayo_13 小时前
React useState setState之后获取到的数据一直是初始值
前端·javascript·react.js
yang9yun13 小时前
PostMan加载三方JS
javascript·测试工具·postman
小小星球之旅13 小时前
SpringBoot实现WebSocket实现用户一对一和一对多信息的发送
spring boot·后端·websocket
Object~13 小时前
2.变量声明
开发语言·前端·javascript