Vue项目中WebSocket封装

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    WEBSOCKET

    封装

    utils下建立WebSocketManager.js

    class WebSocketManager {
        constructor() {
            this.url = null;
            this.websocket = null;
            this.isConnected = false;
            this.listeners = {
                onopen: [],
                onmessage: [],
                onclose: [],
                onerror: [],
            };
            this.reconnectionOptions = {
                enabled: true,
                maxAttempts: 5,
                delay: 3000,
            };
            this.reconnectionAttempts = 0;
            this.connecting = false;
            this.url = null;
            this.preventReconnect = false;
            // 添加Ping-Pong定时器
            this.pingInterval = null;
            this.websocketId = '';
        }
    
        initializeWebSocket(url) {
            sessionStorage.setItem('ws_url', url);
            if (
                !this.websocket ||
                this.websocket.readyState === WebSocket.CLOSED
            ) {
                const websocketId = new Date().getTime();
                this.websocketId = websocketId;
                this.websocket = new WebSocket(url);
                this.url = url;
                this.preventReconnect = false; // 重置标志位
                this.websocket.onopen = (event) => {
                    if (websocketId !== this.websocketId) {
                        return
                    }
                    console.log('onopen', websocketId);
                    this.isConnected = true;
                    this.connecting = false;
                    this.reconnectionAttempts = 0;
                    this.fireListeners('onopen', event);
                    this.websocket.send(`ping`);
                    console.log('send registerEcmsServer');
                    this.startPingPong();
                };
    
                this.websocket.onmessage = (event) => {
                    if (websocketId !== this.websocketId) {
                        return
                    }
                    console.log('onmessage', event.data);
                    try {
                        const jsonData = JSON.parse(event.data);
                        this.fireListeners('onmessage', jsonData);
                    } catch (e) {
                        // console.error('onmessage-err', e);
                    }
                };
    
                this.websocket.onclose = (event) => {
                    console.log('onclose ', event);
                    if (websocketId !== this.websocketId) {
                        console.log('do xxx')
                        return
                    }
                    this.stopPingPong();
                    if (event.code !== 4000) {
                        setTimeout(() => {
                            console.log('reconnect ');
                            this.reconnect();
                        }, 2000);
                    }
                };
    
                this.websocket.onerror = (error) => {
                    if (websocketId !== this.websocketId) {
                        return
                    }
                    console.log('onerror ', error);
                    this.fireListeners('onerror', error);
                };
            } else {
                console.log('Soeket exists, no need to create it, 链接状态',  this.websocket.readyState === WebSocket.OPEN);
            }
        }
    
        close() {
            this.preventReconnect = true;
            this.reconnectionAttempts = 0;
            this.connecting = false;
            this.url = null;
            this.preventReconnect = false;
            this.isConnected = false;
            if (this.websocket) {
                this.websocket.close(4000);
            }
        }
    
        reconnect() {
            if (!this.url && sessionStorage.getItem('ws_url')) {
                return;
            }
            if (!this.preventReconnect && !this.connecting) {
                this.connecting = true;
                this.reconnectionAttempts++;
                setTimeout(() => {
                    this.initializeWebSocket(
                        this.url
                    );
                }, this.reconnectionOptions.delay);
            }
        }
    
        send(message) {
            if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
                this.websocket.send(message);
            }
        }
    
        addEventListener(eventType, callback) {
            if (this.listeners[eventType]) {
                this.listeners[eventType].push(callback);
            }
        }
    
        removeEventListener(eventType, callback) {
            if (this.listeners[eventType]) {
                const index = this.listeners[eventType].indexOf(callback);
                if (index !== -1) {
                    this.listeners[eventType].splice(index, 1);
                }
            }
        }
    
        fireListeners(eventType, event) {
            this.listeners[eventType].forEach((callback) => {
                callback(event);
            });
        }
        startPingPong() {
            if (this.pingInterval) {
                clearInterval(this.pingInterval);
            }
            // 设置Ping间隔ms
            const pingInterval = 20 * 1000;
    
            this.pingInterval = setInterval(() => {
                if (
                    this.websocket &&
                    this.websocket.readyState === WebSocket.OPEN
                ) {
                    // 发送Ping消息
                    this.websocket.send(`ping`);
                }
            }, pingInterval);
        }
    
        stopPingPong() {
            // 停止Ping-Pong定时器
            if (this.pingInterval) {
                clearInterval(this.pingInterval);
                this.pingInterval = null;
            }
        }
    }
    
    const WebSocketManagerInstance = new WebSocketManager();
    
    export default WebSocketManagerInstance;
    
    

    引入

    在main.js中引入

    import Vue from 'vue';
    import Socket from '@/utils/WebSocketManager';
    Vue.prototype.$socket = Socket;
    

    初始化

    const WS= 'ws://127.0.0.1:80/ws';
    this.$socket.initializeWebSocket(WS);
    

    使用

        mounted() {
            this.$socket.addEventListener('onmessage', this.handleWs);
        },
        beforeDestroy() {
            this.$socket.removeEventListener('onmessage', this.handleWs);
        },
        methods: {
            // 处理ws
            handleWs(e) {
                switch (e.method) {
                    // 被动进入庭审
                    case 'XXX':
                        console.log('xxx')
                        break;
                }
            },
        }
    

    如有不足请多指教
    未完待续持续更新
    大家一起进步

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6