websocket 实时通讯 vue3+ts

1、websocket工具    config > index.ts、utils>websocket>index.ts

 
import { ElMessage, getCache } from "@/utils";

function webSocket(params: string) {
  let urlParams: string = params
  const is_reconnect = ref(true); //  是否⾃动重连
  let reconnection: any; // 断线重连后,延迟5秒重新创建WebSocket连接
  let ws: any; // 用于存储实例化后websocket
  let websocketConnectdCount = 0;

  let serverTimeoutObj: any = null;
  let hearbeat_interval = 300000; //  ⼼跳发送频率 一分钟
  const init = () => {
    if (!("WebSocket" in window)) {
      ElMessage({
        message: "抱歉,浏览器不支持Websocket!",
        type: "warning",
        duration: 1000,
      });
      return;
    }
    try {
      // 初始化websocket连接
      initWebSocket();
    } catch (e) {
      console.log("尝试创建连接失败");
      reConnect(); // 如果无法连接上 webSocket 重连
    }
  };

  // 初始化websocket
  function initWebSocket() {
    let baseUrl = import.meta.env.VITE_BaseUrl?.slice(7)
    let url = `ws://${baseUrl}/websocket/${urlParams}`
    ws = new WebSocket(url);
    ws.onopen = function (e: any) {
      websocketOpen(e);
    };

    // 接收
    ws.onmessage = function (e: any) {
      websocketonmessage(e);
    };

    // 连接发生错误
    ws.onerror = function () {
      console.log("WebSocket连接发生错误");
      is_reconnect.value = false; // 连接断开修改标识
      websocketConnectdCount++;
      if (websocketConnectdCount <= 5) {
        reConnect(); // 连接错误 需要重连
      }
    };

    ws.onclose = function (e: any) {
      websocketclose(e);
    };
  }
  // 创建连接
  function websocketOpen(e: any) {
    console.log("连接成功");
    reset();
    start();

    const data = {
      sendType: "HEALTH",
    };
    ws.send(JSON.stringify(data));
  }
  // 数据接收
  const onMessageFns = new Set();
  function websocketonmessage(e: any) {
    if (onMessageFns.size) {
      onMessageFns.forEach((callback) => {
        //@ts-ignore
        callback(e);
      });
    }
    // 如果获取到消息,说明连接是正常的,重置心跳检测
    reset();
    start();
    return e.data;
  }
  // 关闭
  function websocketclose(e: any) {
    console.log(e);
    is_reconnect.value = false; // 断开后修改标识
    console.log("connection closed (" + e.code + ")");
  }

  // 数据发送
  function websocketsend(data: any) {
    if (!["number", "string"].includes(typeof data)) {
      data = JSON.stringify(data);
    }
    ws.send(data);
  }
  // 发送
  function sendWebSocket(data: any) {
    if (ws.readyState === ws.OPEN) {
      // 开启状态
      websocketsend(data);
    } else {
      // 若 未开启 / 正在开启 状态 ,则等待1s后重新调用
      setTimeout(function () {
        sendWebSocket(data);
      }, 1000);
    }
  }

  // 定义重连函数
  let reConnect = () => {
    console.log("尝试重新连接");
    if (is_reconnect) return; // 如果已经连上就不在重连了
    reconnection && clearTimeout(reconnection);
    reconnection = setTimeout(function () {
      // 延迟5秒重连  避免过多次过频繁请求重连
      init();
    }, 5000);
  };

  window.onbeforeunload = function () {
    ws.close();
  };

  //心跳
  let reset = () => {
    clearTimeout(serverTimeoutObj);
  };
  const start = () => {
    serverTimeoutObj = setInterval(() => {
      if (ws.readyState === 1) {
        console.log("连接状态,发送消息保持连接");
        const data = {
          sendType: "HEALTH",
        };
        ws.send(JSON.stringify(data));
        reset(); // 如果获得消息 说明连接正常 重置心跳检测
      } else {
        console.log("断开连接, 尝试重连");
        webSocket(urlParams);
      }
    }, hearbeat_interval);
  };
  init();
  return {
    sendWebSocket,
    onMessageFns,
  };
}
export default webSocket;

3、页面使用

import webSocket from "@/utils/websocket";

const userId = getCache("userId");
const ws = webSocket(userId)!;

onMounted(async () => {
const addMessage = () => {
  ws.onMessageFns.add((value: any) => {
    if (value.data !== "来自后台的反馈:连接成功" && value.data !== "SUCCESS") {
    
      if (JSON.parse(value.data)) {
         console.log("获取到的信息",JSON.parse(value.data))
      }
    }
  });
};
});

猜你喜欢

转载自blog.csdn.net/M__O__M/article/details/130882984