vue封装websocket,支持心跳机制,支持断开重连机制

代码逻辑简单明了.注释易懂.不做过多的描述.这个封装已在实际项目中使用.如有BUG会及时更新本文

简要说明:handleWsMessage 是统一处理接受消息的方法.接受消息后会存入VUEX中方面页面调用

/*
 * @Author: Davi 
 * @Date: 2023-04-21 18:29:33 
 * @Last Modified by: Davi
 * @Last Modified time: 2023-04-27 16:14:02
 */
import {
    
     handleWsMessage } from './handler';
let IP = '192.168.1.7'; // 获取项目信息中的IP
let PORT = '9999'; // 获取项目信息中的端口
const wsurl = `ws://${
      
      IP}:${
      
      PORT}/ibms-device/ws?token=`
export class IbmsSocket {
    
    
    // 初始化实例
    constructor(token, maxReconnectCount) {
    
    
        this.websocket = null;
        this.url = wsurl + token;
        this.reconnectInterval = 1000 * 10; // 重连间隔
        this.heartBeatInterval = 5000; // 心跳间隔
        this.heartBeatTimer = null; // 心跳计时
        this.reconnectCount = 0; // 当前重连的次数
        this.maxReconnectCount = maxReconnectCount || 10; // 最大重连次数
        this.isReconnecting = false // 是否正在重连
    }
    // 初始化
    init () {
    
    
        return new Promise((resolve, reject) => {
    
    
            this.websocket = new WebSocket(this.url);

            // 注册 WebSocket 事件监听器
            this.websocket.onmessage = this.onMessage.bind(this);
            this.websocket.onopen = this.onOpen.bind(this);
            this.websocket.onclose = this.onClose.bind(this);
            this.websocket.onerror = this.onError.bind(this);

            // 保存 websocket 实例对象到全局 window 对象中
            if (window.websocket) {
    
    
                window.websocket.close();
            }
            window.websocket = this.websocket;

            resolve(this);
        })
    }
    onOpen () {
    
    
        console.log('%cwebsocket连接成功!', 'color: #2ccd70');
        // 启动心跳机制
        this.startHeartBeat();
        // // 监听 WebSocket 关闭事件
        // this.websocket.addEventListener('close', (event) => {
    
    
        //     console.log('WebSocket closed:', event.code, event.reason);
        //     console.log(this.websocket.readyState === WebSocket.CLOSED, 'code');
        //     // 停止心跳机制
        //     this.stopHeartBeat();
        //     // 如果还没达到最大重连次数,则继续重连
        //     if (this.reconnectCount < this.maxReconnectCount) {
    
    
        //         this.reconnectCount++;
        //         setTimeout(() => {
    
    
        //             console.log(`WebSocket 重连中...(第 ${this.reconnectCount} 次)`);
        //             this.init();
        //         }, this.reconnectInterval);
        //     }
        // });
    }
    // 接受消息
    onMessage (evt) {
    
    
        // 处理消息
        handleWsMessage(evt.data);
    }
    // 发送消息
    sendMessage (data) {
    
    
        return new Promise((resolve, reject) => {
    
    
            console.log(`%c发送消息-->${
      
      data}`, 'color:#2ccd70')
            this.websocket.send(data);
            resolve()
        })
    }

    // 客户端主动断开
    closeWs () {
    
    
        this.websocket.close()
        window.websocket = null;
    }
    // 关闭连接
    onClose (event) {
    
    
        console.log('关闭连接', event.code, event.reason);
        this.stopHeartBeat();
        if (!this.isReconnecting && this.reconnectCount < this.maxReconnectCount) {
    
    
            this.isReconnecting = true // 标记正在重连
            this.reconnectCount++
            setTimeout(() => {
    
    
                this.init()
                    .then(() => {
    
    
                        console.log(`WebSocket 重连中...(第 ${
      
      this.reconnectCount} 次)`);
                    })
                    .catch(() => {
    
    
                        console.log('重连失败!')
                    })
                    .finally(() => {
    
    
                        this.isReconnecting = false // 重连结束
                    })
            }, this.reconnectInterval)
        }
    }


    // 连接错误
    onError (error) {
    
    
        console.log('发生错误');
    }

    // 开始心跳
    startHeartBeat () {
    
    
        this.heartBeatTimer = setInterval(() => {
    
    
            this.sendMessage(JSON.stringify({
    
     "type": "HEARTBEAT" }))
        }, this.heartBeatInterval)
    }
    // 停止心跳
    stopHeartBeat () {
    
    
        clearInterval(this.heartBeatTimer)
    }
}

页面使用:
1.引入封装import { IbmsSocket } from '@/websocket';
2.初始化调用:

 // 初始化webSocket
        async createdSocket() {
    
    
            if (!window.websocket) {
    
    
                let token = getTokenValue();
                new IbmsSocket(token).init().then((websocket) => {
    
    
                    this.$store.commit('websocket/SET_WEBSOCKET', websocket); // 将websocket这个对象存入VUEX中
                });
            }
        },

说明:websocket是全局的所以会把他存入VUEX中

猜你喜欢

转载自blog.csdn.net/weixin_45906632/article/details/130409889