问题重现:

后台服务重启时,前端连接的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);
    }

     

 

Logo

前往低代码交流专区

更多推荐