• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

websocket心跳及重连机制

互联网 diligentman 2周前 (01-12) 5次浏览

websocket心跳及重连机制

websocket是前后端交互的长连接,前后端也都可能因为一些情况导致连接失效并且相互之间没有反馈提醒。因此为了保证连接的可持续性和稳定性,websocket心跳重连就应运而生。

在使用原生websocket的时候,如果设备网络断开,不会立刻触发websocket的任何事件,前端也就无法得知当前连接是否已经断开。这个时候如果调用websocket.send方法,浏览器才会发现链接断开了,便会立刻或者一定短时间后(不同浏览器或者浏览器版本可能表现不同)触发onclose函数。

后端websocket服务也可能出现异常,造成连接断开,这时前端也并没有收到断开通知,因此需要前端定时发送心跳消息ping,后端收到ping类型的消息,立马返回pong消息,告知前端连接正常。如果一定时间没收到pong消息,就说明连接不正常,前端便会执行重连。

心跳机制

心跳机制是每隔一段时间会向服务器发送一个数据包,告诉服务器自己还活着,同时客户端会确认服务器端是否还活着,如果还活着的话,就会回传一个数据包给客户端来确定服务器端也还活着,否则的话,有可能是网络断开连接了,需要重连。

当成功建立连接后,即启动心跳检测,大概的流程如下图:

websocket心跳及重连机制

export default {
    name: 'App',
    data () {
        return {
            isOpen:false,//是否连接
            pingIntervalSeconds:3000,//心跳连接时间
            lockReconnect: false,//是否真正建立连接
            heartTimer: null,//心跳定时器
            serverTimer: null,//服务器超时 定时器
            reconnectTimer: null,//断开 重连倒计时
            sendFixHeartTimer:null,//20s固定发送心跳定时器
        }
    },
    created(){
        this.connect();
    },
    methods:{
        // ws连接
        connect(){
            ws.WebSocket('wss://ws.51vv.com/game','');
            // 监听连接开启,
            ws.onopen(e => {
                //开启心跳
                this.start();
                this.sendFixHeart();
            });
            ws.onmessage(e => {
                // 收到服务器信息,心跳重置,上报
                this.reset();
            });
            ws.onerror(e => {
                //重连
                this.reconnect();
            });
            ws.onclose(e => {
                //重连
                this.reconnect();
            });
        },
        //开启心跳
        start(){
            this.heartTimer && clearTimeout(this.heartTimer);
            this.serverTimer && clearTimeout(this.serverTimer);
            this.heartTimer = setTimeout(()=>{
                this.send({
                    cmd:1100,
                });
                //超时关闭,超时时间为5s
                this.serverTimer = setTimeout(()=>{
                    ws.close();
                }, 5000);
            }, this.pingIntervalSeconds)
        },
        //重新连接  3000-5000之间,设置延迟避免请求过多
        reconnect(){
            //设置lockReconnect变量避免重复连接
            if(this.lockReconnect) return;
            this.lockReconnect = true;
            this.reconnectTimer && clearTimeout(this.reconnectTimer);
            this.reconnectTimer = setTimeout(()=> {
                this.connect();
                this.lockReconnect = false;
            }, parseInt(Math.random()*2000 + 3000));
        },
        //重置心跳
        reset(){
            clearTimeout(this.heartTimer);
            clearTimeout(this.serverTimer);
            this.start();
        },
        // 20s固定发送心跳
        sendFixHeart(){
            clearInterval(this.sendFixHeartTimer);
            this.sendFixHeartTimer = setInterval(()=>{
                this.send({
                    cmd:1100,
                });
            }, 20000);
        }

    }
}

喜欢 (0)