根据自己的业务进行修改,这边只是提供个思路。
第一: 首先新建websocket.js 对它进行封装
let webSock = null;
let connectState = false; // 标记 WebSocket 连接状态
let rec; //断线重连后,延迟5秒重新创建WebSocket连接 rec用来存储延迟请求的代码
let closeFlag = false; // 是否关闭socket
let global_callback = null;
let port = "8080"; // webSocket连接端口
let wsUrl = `${import.meta.env.VITE_APP_BASE_WEBSOCKET}?userId=${sessionStorage.getItem('webSocketId')}`
function createWebSocket(callback) {
if (webSock != null) {
return
}
webSock = new WebSocket(wsUrl);
global_callback = callback
webSock.onopen = function () {
// 连接打开时的处理
websocketOpen();
};
webSock.onmessage = function (e) {
// 接收消息时的处理
websocketOnMessage(e);
};
webSock.onclose = function (e) {
// 连接关闭时的处理
websocketClose(e);
};
// 连接发生错误的回调方法
webSock.onerror = function () {
websocketError();
};
}
//心跳设置
const heartCheck = {
timeout: 30000, //每段时间发送一次心跳包 这里设置为20s
timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
start: function () {
this.timeoutObj = setInterval(function () {
if (connectState) webSock.send(JSON.stringify({type: 0}));
}, this.timeout);
},
reset: function () {
clearTimeout(this.timeoutObj);
this.start();
}
};
//定义重连函数
let reConnect = () => {
console.log("尝试重新连接");
if (connectState) return; //如果已经连上就不在重连了
rec && clearTimeout(rec);
rec = setTimeout(function () { // 延迟5秒重连 避免过多次过频繁请求重连
if (!connectState) {
createWebSocket();
}
}, 5000);
};
// 实际调用的方法
function sendSock(agentData) {
if (webSock.readyState === webSock.OPEN) {
// 若是ws开启状态
webSock.send(agentData)
} else if (webSock.readyState === webSock.CONNECTING) {
// 若是 正在开启状态,则等待1s后重新调用
setTimeout(function () {
sendSock(agentData);
}, 1000);
} else {
// 若未开启 ,则等待1s后重新调用
setTimeout(function () {
sendSock(agentData);
}, 1000);
}
}
function websocketClose() {
connectState = false;
webSock = null;
global_callback = null;
closeFlag = false;
heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
// 清除重连定时器
rec && clearTimeout(rec);
}
// 数据接收
function websocketOnMessage(msg) {
if (!msg || !msg.data) {
// 可能得情况 - 心跳机制、无关信息接收
console.log("收到数据:空消息");
return;
}
// 收到信息为Blob类型时
let result = JSON.parse(msg.data);
if (result.type === 0 || result.type === '0') {
//自己的业务
} else {
global_callback(result)
}
}
function closeSock({activeClose = false}) {
closeFlag = activeClose;
// 清除心跳定时器
heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
// 清除重连定时器
rec && clearTimeout(rec);
if (closeFlag) {
// 关闭socket
webSock.close();
}
// 初始化相关变量
webSock = null;
connectState = false;
}
const websocketError = () => {
closeSock({activeClose: true});
// 执行重连
reConnect();
}
function websocketOpen(e) {
connectState = true;
heartCheck.start(); //发送心跳 看个人项目需求
}
export {sendSock, createWebSocket, closeSock};
第二: 在store 中建立 websocketStore.js
import {sendSock, createWebSocket, closeSock} from '@/utils/websocket.js'
const websocketStore = defineStore(
'websocket',
{
state: () => ({
webSocketList: {
bizType: null,
content: '',
id: '',
remindLevel: 0,
senderId: null,
type: 1,
userId: null
},
}),
actions: {
init() {
console.log('websocket init')
createWebSocket(this.handleData)
},
handleData (res){
console.log('websocket handleData',res)
Object.assign(this.webSocketList,res)
}
}
})
export default websocketStore
第三:在vue 中任何地方都可以监听数据的变化了
const userWebsocket = websocketStore()
watch(userWebsocket.webSocketList, (newVal) => {
console.log('监听数据变化')
console.log(newVal)
}
);
onMounted(() => {
nextTick(() => {
userWebsocket.init()
})
})