uniapp + vue3 + ts中封装WebSocket Hooks,适用于uniapp平台,支持心跳检测,断开重连,主动断开,消息回调,主动发消息

478 阅读1分钟

Hooks定义(话不多说,直接上代码,拿来即用)

import { ref, onMounted, onUnmounted } from 'vue';

/**
 * @description uniapp websocket hook
 * @param url websocket url ws:xxx
 * @param onMessage 收到消息的回调
 * @param heartbeatInterval 心跳间隔时间
 */
export default function useUniWebSocket(url:string, onMessage:(res:any)=>void,heartbeatInterval = 3000,) {
  // 保存socket实例
  const socketTask = ref(null as any);
  // 是否主动断开连接
  const isDisconnect = ref(false);
  // 心跳定时器
  let heartbeatTimer = null as any;
  // 连接
  const connect = () => {
    if (!socketTask.value || isDisconnect.value) {
      isDisconnect.value = false;
      console.log('WebSocket连接中...',url)
      console.log('socketTask',socketTask)
      socketTask.value = uni.connectSocket({
        url: url,
        complete: () => {
          console.log('WebSocket连接已建立');
          startHeartbeat();
        },
      });
      // 监听WebSocket连接打开事件
      socketTask.value.onOpen(() => {
        console.log('WebSocket连接已打开');
      });
      // 监听WebSocket关闭
      socketTask.value.onClose(() => {
        console.log('WebSocket连接已关闭');

        if (!isDisconnect.value) {
          setTimeout(() => {
            console.log('WebSocket重新连接');
            connect();
          }, 1000);
        }
      });
      // 监听WebSocket错误
      socketTask.value.onError((error:any) => {
        console.error('WebSocket连接发生错误:', error);
      });
      // 监听WebSocket接受到服务器的消息事件
      socketTask.value.onMessage((res:{data:string}) => {
        let data = JSON.parse(res.data)
        if (onMessage) {
          onMessage(data);
        }
      });
    }
  };
  // 断开连接
  const disconnect = () => {
    if (socketTask.value) {
      isDisconnect.value = true;
      socketTask.value.close({});
      stopHeartbeat();
      socketTask.value = null;
    }
  };
  
  // 发送心跳
  const startHeartbeat = () => {
    heartbeatTimer = setInterval(() => {
      if (socketTask.value) {
        console.log('发送心跳')
        socketTask.value.send({
          data: JSON.stringify({})
        });
      }
    }, heartbeatInterval);
  };
  // 停止心跳
  const stopHeartbeat = () => {
    clearInterval(heartbeatTimer);
  };
  // 发送消息
  const sendMessage = (message:any) => {
    console.log('发送消息:socketTask.value', socketTask.value)
    if (socketTask.value) {
      socketTask.value.send({
        data: JSON.stringify(message)
      });
    }
  };

  onMounted(() => {
    connect();
  });

  onUnmounted(() => {
    disconnect();
  });

  return {
    socketTask,
    connect,
    disconnect,
    sendMessage,
  };
}