6

websocket心跳及重连机制

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

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

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

心跳机制

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

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

未命名文件(1).png

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);
        }

    }
}


  1. 客户端发起心跳
  • 网页关闭会主动触发服务端事件onclose
  • 手动断网会触发客户端onerror,再次打开网络时不会触发客户端onclose,onerror事件.(需要监听网络情况,有网时重连)
  • 用开发者工具断网时,长时间会触发客户端onclose,onerror事件,再次打开网络时也会触发客户端onclose,onerror事件
  • 电梯中断网会一直触发客户端onerror事件~~~~

2.服务端发起心跳


suyue
77 声望7 粉丝

« 上一篇
页面监控
下一篇 »
websocket原理