解决后台服务重启后,前端webSocket断了的问题

1,716 阅读2分钟

后端服务器宕机或重启时,前端Vue 不断重连webSocket的解决办法:

问题重现:后台服务重启时,前端连接的webScoket就断了,需要刷新页面才能重新建立连接,这样用户体验的效果不好,而且有些业务场景,比如硬件监控系统大屏这些是不允许刷新页面的,所以需要前端发现webSocket断了,然后自己不断去发起连接。

解决思路:在webSocket的生命周期onclose和onerror时调用重连函数,增加心跳检测。

解决方案:

  1. 创建变量

    data() {    
        return {        
            // webSocket对象		
            webSocket: null,		
            // webSocketUrl地址		
            webSocketUrl: null,		
            //连接标识 避免重复连接		
            isConnect: false,		
            //断线重连后,延迟5秒重新创建WebSocket连接  rec用来存储延迟请求的代码		
            rec: null,		
            // 心跳发送/返回的信息		
            checkMsg: {hhh: 'heartbeat'},		
            //每段时间发送一次心跳包 这里设置为20s		
            timeout: 20000,		
            //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)		
            timeoutObj: null,    
        }
    }
    
  2. 创建webSocket连接

    //创建webSocket连接
    createWebSocket() {    
    let that = this;	that.webSocket = new WebSocket(that.webSocketUrl);	
    that.initWebsocket();
    }
    
  3. 初始化webSocket连接

    initWebsocket() {    
        let that = this;	
        //WebSocket连接建立之后会调用onopen方法	
        that.webSocket.onopen = that.websocketonopen;	
        //当websocket收到服务器发送的信息之后  会调用onmessage方法 	
        that.webSocket.onmessage = that.websocketonmessage;	
        //当websocket因为各种原因(正常或者异常)关闭之后,会调用onclose方法	
        that.webSocket.onclose = that.websocketclose;	
        //当websocket因为异常原因(比如服务器部署、断网等)关闭之后,会调用onerror方法	
        //在onerror中需要调用reConnect方法重连服务器	
        that.webSocket.onerror = that.websocketonerror;
    }
    
  4. websocketonopen函数

    websocketonopen() {	
        let that = this;	
        console.log('open');	
        //连接建立后修改标识	
        that.isConnect = true;	
        // 建立连接后开始心跳	
        // 因为nginx一般会设置例如60s没有传输数据就断开连接  所以要定时发送数据	
        that.timeoutObj = setTimeout(function() {		
        if (that.isConnect)		    
            that.webSocket.send(that.checkMsg);    
    }, that.timeout);
    }
    
  5. websocketonerror函数

    websocketonerror() {	
        let that = this;	
        console.log('error');	
        //连接断开后修改标识	
        that.isConnect = false;	
        //连接错误 需要重连	
        that.reConnect();
    }
    
  6. websocketonmessage函数

    websocketonmessage(e) {    
        // 拿到数据,处理自己的业务	
        let that = this;	
        console.log(e.data);					
        //获取消息后 重置心跳	
        clearTimeout(that.timeoutObj);	
        that.timeoutObj = setTimeout(function() {	
        if (that.isConnect)		
            that.webSocket.send(that.checkMsg);	
    }, that.timeout);
    }
    
  7. websocketclose函数

    websocketclose() {    
        let that = this;	
        console.log('close');	
        //连接断开后修改标识	
        that.isConnect = false;	
        //连接错误 需要重连	
        that.reConnect();
    }
    
  8. 定义重连函数

    reConnect() {    
        let that = this;	
        console.log('尝试重新连接');	
        //如果已经连上就不在重连了	
        if (that.isConnect) {		
        return;	
    }	
    clearTimeout(that.rec);	
    // 延迟5秒重连  避免过多次过频繁请求重连	
    that.rec = setTimeout(function() {		
        that.createWebSocket();	
    }, 5000);
    }