1.创建文件webSocket.ts(我创建的路径@/utils/webSocket.ts)

// webSocket.ts
let WSS_SERVER_URL ="wss://后端给的链接"
type WebSocketUrl = string;

interface WebSocketMessage {
  state: number;
  method: string;
}

interface SendMessageOptions {
  data: string;
}

interface CloseSocketOptions {
  reason?: string;
  success?: () => void;
  fail?: (err: any) => void;
}

class webSocketClass {
  private url: WebSocketUrl | string;
  private data: WebSocketMessage | null = null;
  private isCreate: boolean = false; // WebSocket 是否创建成功
  private isConnect: boolean = false; // 是否已经连接
  private isInitiative: boolean = false; // 是否主动断开
  private timeoutNumber: number; // 心跳检测间隔(秒)
  private heartbeatTimer: ReturnType<typeof setInterval> | null = null; // 心跳检测定时器
  private reconnectTimer: ReturnType<typeof setTimeout> | null = null; // 断线重连定时器
  private socketExamples: UniNamespace.SocketTask | null = null; // websocket实例
  private againTime: number; // 重连等待时间(单位秒)&&金价刷新时间
  private timeOut: boolean = false; // 是否连接超时

  constructor(url: string = WSS_SERVER_URL, time: number = 60) {
    this.url = url;

    this.timeoutNumber = time;
    this.againTime = 1;
    this.initSocket();
  }

  // 初始化websocket连接
  public initSocket(): void {
    try {
      this.socketExamples = uni.connectSocket({
        url: this.url,
        success: () => {

          this.isCreate = true;
        },
        fail: () => {
          this.isCreate = false;
        },
      });
      this.createSocket();
    } catch (error) {
    }
  }

  // 创建websocket连接
  private createSocket(): void {
    if (this.isCreate && this.socketExamples) {
      // 监听 WebSocket 连接打开事件
      try {
        this.socketExamples.onOpen(() => {
          this.isConnect = true;
          if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
          if (this.reconnectTimer) clearTimeout(this.reconnectTimer);

          // 打开心跳检测(根据项目需求,可自行决定是否启用心跳检测)
          // this.heartbeatCheck();
        });

        // 监听 WebSocket 接受到服务器的消息事件
        this.socketExamples.onMessage((res) => {
          const data = JSON.parse(res.data);
          uni.$emit("marketUpdate", data);
        });

        // 监听 WebSocket 连接关闭事件
        this.socketExamples.onClose(() => {
          this.isConnect = false;
          this.reconnect();
        });

        // 监听 WebSocket 错误事件
        this.socketExamples.onError((res) => {
          this.timeOut =
            res.errMsg.includes("Timed") || res.errMsg.includes("Invalid HTTP");
        });
      } catch (error) {
        console.warn(error);
      }
    } else {
      console.warn("WebSocket 初始化失败!");
    }
  }

  // 发送消息
  public sendMsg(value: WebSocketMessage): Promise<boolean> {
    const param = JSON.stringify(value);
    return new Promise((resolve, reject) => {
      if (!this.socketExamples) {
        reject(new Error("WebSocket 实例未初始化"));
        return;
      }

      this.socketExamples.send({
        data: param,
        success() {
          resolve(true);
        },
        fail(error) {
          reject(error);
        },
      });
    });
  }

  // 开启心跳检测
  private heartbeatCheck(): void {
    this.data = {
      state: 1,
      method: "heartbeat",
    };

    this.heartbeatTimer = setInterval(() => {
      if (this.data) {
        this.sendMsg(this.data);
      }
    }, this.timeoutNumber * 1000);
  }

  // 重新连接
  private reconnect(): void {
    // 停止发送心跳
    if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
    if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);

    // 如果不是人为关闭的话,进行重连
    if (!this.isInitiative) {
      this.reconnectTimer = setTimeout(() => {
        this.initSocket();
      }, this.againTime * 1000);
    }
  }

  public setIsInitiativeFalse(): void {
    this.isInitiative = false;
  }

  public setIsInitiativeTrue(): void {
    this.isInitiative = true;
  }

  // 关闭 WebSocket 连接
  public closeSocket(reason: string = "关闭"): void {
    if (this.socketExamples) {
      this.socketExamples.close({
        reason,
        success: () => {
          this.data = null;
          this.isCreate = false;
          this.isConnect = false;
          this.isInitiative = true;
          this.socketExamples = null;
          if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
          if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
        },
        fail: (err) => {
        },
      });
    }
  }
}

export default webSocketClass;

2.使用

在入口文件APP.vue中引入并创建实例,连接websocket

<script setup lang="ts">
const websocketUtil = new WebsocketUtil(); // 创建 WebSocket 工具类实例
provide("websocketUtil", websocketUtil); // 提供给所有子组件
</script>

在需要的页面使用

<script setup lang="ts">
let websocketUtil = inject("websocketUtil");
onShow(() => {
  // 接收后端数据
  uni.$on("onMessage", (data) => {
    //业务逻辑
  });
});
//使用websocket给后端发送信息
function sendMsg(){
 websocketUtil.sendMsg(params);
}
</script>

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐