vue3+pinia 封装 websocket,全局可用

1,577 阅读2分钟

根据自己的业务进行修改,这边只是提供个思路。

第一: 首先新建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()
  })
})