WebSocket心跳机制/服务器端开连接(JS前端)

情景: 前端使用 WebSocket 的时候,后端长时间没有推送数据,导致 WebSocket 连接经常断开,后端也会报错。

解决方法: 通过 心跳机制 让前端和后端始终保持连接。

代码:

// WebSocket心跳检测
var ws_heartCheck = {
    timeout: 5000,			// 5秒一次心跳
    timeoutObj: null,		// 执行心跳的定时器
    serverTimeoutObj: null,	// 服务器超时定时器
    reset: function(){		// 重置方法
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        return this;
    },
    start: function(){		// 启动方法
        var self = this;
        this.timeoutObj = setTimeout(function(){
            // 这里发送一个心跳信息,后端收到后,返回一个消息,在onmessage拿到返回的心跳(信息)就说明连接正常
            ws.send("check");
			// 如果超过一定时间还没重置,说明后端主动断开了
            self.serverTimeoutObj = setTimeout(function(){
				// 如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                ws.close();
            }, self.timeout);
        }, this.timeout);
    }
}

使用方法:

// WebSocket
var ws = null;
// WebSocket连接地址
var ws_url = 'ws://localhost:8888'

// 创建WebSocket
ws_create(ws_url);

// 创建WebSocket
function ws_create(url) {
	 try{
		// 判断是否支持 WebSocket
        if('WebSocket' in window){
			// 连接WebSocket
            ws = new WebSocket(url);
			// 初始化WebSocket事件(WebSocket对象, WebSocket连接地址)
			ws_event(ws, url);
        }
    }catch(e){
		// 重新连接WebSocket
        ws_recontent(url);
        console.log(e);
    }
}

// WebSocket 事件创建
function ws_event(ws, url) {
	ws.onopen = function (event) {
		// 心跳检测重置
		ws_heartCheck.reset().start();
		console.log("WebSocket已连接");
	};

	ws.onclose = function (event) {
		// 重新连接WebSocket
        ws_recontent(url);
		console.log("WebSocket连接已关闭");
	};

	ws.onerror = function (event) {
		// 重新连接WebSocket
        ws_recontent(url);
		console.log("WebSocket错误:", event);
	};

	ws.onmessage = function (event) {
		// 只要有数据,那就说明连接正常
		ws_heartCheck.reset().start();

		// 处理数据,只处理非心跳检测的数据
		if (event.data != 'check') {
		  // 处理数据
		}
	};
}

// 重新连接websocker(WebSocket连接地址)
function ws_recontent(url) {
	// 延迟避免请求过多
	setTimeout(function () {
		ws_create(url);
	}, 2000);
}

// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,这样服务端会抛异常。
window.onbeforeunload = function() {
    ws.close();
} 

// WebSocket心跳检测
var ws_heartCheck = {
    timeout: 5000,			// 5秒一次心跳
    timeoutObj: null,		// 执行心跳的定时器
    serverTimeoutObj: null,	// 服务器超时定时器
    reset: function(){		// 重置方法
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        return this;
    },
    start: function(){		// 启动方法
        var self = this;
        this.timeoutObj = setTimeout(function(){
            // 这里发送一个心跳信息,后端收到后,返回一个消息,在onmessage拿到返回的心跳(信息)就说明连接正常
            ws.send("check");
			// 如果超过一定时间还没重置,说明后端主动断开了
            self.serverTimeoutObj = setTimeout(function(){
				// 如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                ws.close();
            }, self.timeout);
        }, this.timeout);
    }
}

注意: 后端收到以后需要给前端返回数据,否则还是无法保持连接

代码参考了:https://blog.csdn.net/cai4561/article/details/106809244

  • 12
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值