Vue项目中WebSocket封装

发布时间:2023年12月17日

封装

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://blog.csdn.net/qq_40440961/article/details/134925054
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。