vue3使用websocket,并有失败重连的方法

效果图

在这里插入图片描述

utils/websocket.js

let websock = null;
let global_callback = null;
let linkFailCount = 0; // 连接次数,目前连接三次
let relinkLoading = null;// 重连全屏loading
// const serverPort = "8080"; // webSocket连接端口

// const wsuri = `ws://192.168.1.30:18081/intelligent-learning/openApi/socket/${uId}`;
function createWebSocket(callback,uId) {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  // console.log(uId,'uId666');
  if (websock == null || typeof websock !== WebSocket) {
    initWebSocket(callback,uId);
  }
}
function initWebSocket(callback,val) {
  global_callback = callback;
  // 初始化websocket
  websock = new WebSocket(`ws://192.168.1.30:18081/intelligent-learning/openApi/socket/${val}`);
  // websock = new WebSocket(`ws://xgxt.glutnn.cn:8080/intelligent-learning/openApi/socket/${val}`);
  // console.log(websock,'报什么错??');
  websock.onmessage = function (e) {
    websocketonmessage(e);
  };
  websock.onclose = function (e) {
    websocketclose(e);
  };
  websock.onopen = function () {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    websocketOpen();
  };
  // 连接发生错误的回调方法
  // 方法一
  // websock.onerror = function (err) {
  //   console.log("WebSocket连接发生错误");
  //   //createWebSocket();啊,发现这样写会创建多个连接,加延时也不行

  //   // 新加的
  //   console.log('websocket 断开: ' + err, websock.readyState)
  //       if (websock.readyState != 0) {
  //         setTimeout(() => {
  //           createWebSocket()
  //         }, 30000)
  //       }
  // };

  // 方法二
  websock.onerror = webSocketOnError; // 连接错误处理

}
// 实际调用的方法
function sendSock(agentData) {
  if (websock.readyState === websock.OPEN) {
    // 若是ws开启状态
    websocketsend(agentData);
  } else if (websock.readyState === websock.CONNECTING) {
    // 若是 正在开启状态,则等待1s后重新调用
    setTimeout(function () {
      sendSock(agentData);
    }, 1000);
  } else {
    // 若未开启 ,则等待1s后重新调用
    setTimeout(function () {
      sendSock(agentData);
    }, 1000);
  }
}
function closeSock() {
  websock.close();
}
// 数据接收
function websocketonmessage(msg) {
  // console.log("收到数据:"+JSON.parse(e.data));
  // console.log("收到数据:"+msg);
  // global_callback(JSON.parse(msg.data));
  // 收到信息为Blob类型时
  let result = null;
  // debugger
  if (msg.data instanceof Blob) {
    const reader = new FileReader();
    reader.readAsText(msg.data, "UTF-8");
    reader.onload = (e) => {
      console.log(e);
      if (typeof reader.result === "string") {
        result = JSON.parse(reader.result);
      }
      //console.log("websocket收到", result);
      global_callback(result);
    };
  } else {
    result = JSON.parse(msg.data);
    //console.log("websocket收到", result);
    global_callback(result);
  }
}
// 数据发送
function websocketsend(agentData) {
  console.log("发送数据:" + agentData);
  websock.send(agentData);
}
// 关闭
function websocketclose(e) {
  console.log("connection closed (" + e.code + ")");

  if (linkFailCount < 3 && websock && (websock.readyState >= 2)) {
    // 开启重连加载动画
    relinkLoading = ElLoading.service({
        lock: true,
        text: `连接关闭了,正在重连,请稍等...`,
    })
    initWebSocket();
}
}
function websocketOpen(e) {
  console.log(e);
  console.log("连接打开");

  linkFailCount = 0;// 打开连接,连接次数改为0
    // 加载动画如果开启,则关闭
    if (relinkLoading) {
        relinkLoading.close();
    }
}

// 失败重连的方法
function webSocketOnError(e) {
  linkFailCount++;// 连接失败的次数
  if (relinkLoading) {
      relinkLoading.close(); // 关闭重连加载动画
  }
  //连接三次
  if (linkFailCount < 3) {
       initWebSocket();
      // 开启重连加载动画
      relinkLoading = ElLoading.service({
          lock: true,
          text: `${linkFailCount}次连接失败,正在尝试第${linkFailCount + 1}次重新连接,请稍等...`,
      })
  } else {
      ElMessageBox.confirm(
          '连接失败,是否尝试刷新?',
          '警告',
          {
              confirmButtonText: '刷新',
              cancelButtonText: '取消',
              type: 'warning',
              "close-on-click-modal": false
          }
      )
          .then((e) => {
              if (e == "confirm") {
                  location.reload();
                  initWebSocket();
              }
          })
  }
}

export { sendSock, createWebSocket, closeSock };

store/webSocket.js

import { defineStore } from "pinia";

export const useWebSocketStore = defineStore("useWebSocketStore", {
  state: () => {
    return {
      data: [],
    };
  },
  actions: {
    addMsg(val) {
      this.data.push(val);
    },
  },
  getters: {

  },
});

如果想在全局使用websocket,可以放在app.vue里面使用

app.vue



<template>
  <div class="app" v-wechat-title="$route.meta.title">
  <el-config-provider :locale="locale">
    <router-view></router-view>
  </el-config-provider>
  </div>
</template>

<script setup>
import { ref, reactive, toRefs, getCurrentInstance } from "vue";
import { useWebSocketStore } from "@/store/webSocket";
import { createWebSocket } from "@/utils/websocket";
import { ElNotification } from "element-plus";

const webSocket = useWebSocketStore();
const studentId=ref(localStorage.getItem('loginuserId'))

// 消息的方法
const mes = ref();
const global_callback = (msg) => {
  console.log("websocket的回调函数收到服务器信息:" + JSON.stringify(msg));
  // console.log("收到服务器信息:" + msg);
  mes.value = JSON.parse(JSON.stringify(msg));
  // console.log(mes.value,'这里有没有数据先',);
  webSocket.addMsg(mes);
  ElNotification({
    title: mes.value.title,
    message: mes.value.content,
    offset: 110,
    // position: 'bottom-right',
    type: 'warning',
    duration: 0,
  });
};

createWebSocket(global_callback,studentId.value);


</script>
<style >
 
.el-upload-list {
    margin: 10px 0 0;
    padding: 0;
    list-style: none;
    position: relative;
    display: none;
}



</style>

参考

  1. https://blog.csdn.net/kk12138123/article/details/128189610
  2. 失败重连参考https://blog.csdn.net/liuxin00020/article/details/127553530
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值