`

工作笔记5 - websocket心跳重连机制

阅读更多

心跳重连缘由

在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时性关闭,这时候websocket的连接已经断开,

而浏览器不会执行websocket 的 onclose方法,我们无法知道是否断开连接,也就无法进行重连操作。

如果当前发送websocket数据到后端,一旦请求超时,onclose便会执行,这时候便可进行绑定好的重连操作。

因此websocket心跳重连就应运而生。

 

如何实现

在websocket实例化的时候,我们会绑定一些事件:

 
var ws = new WebSocket(url);
ws.onclose = function () {
    //something
};
ws.onerror = function () {
    //something
};
        
ws.onopen = function () {
   //something
};
ws.onmessage = function (event) {
   //something
}
 

如果希望websocket连接一直保持,我们会在close或者error上绑定重新连接方法。

 
ws.onclose = function () {
    reconnect();
};
ws.onerror = function () {
    reconnect();
};
    
 

这样一般正常情况下失去连接时,触发onclose方法,我们就能执行重连了。

 

那么针对断网的情况的心跳重连,怎么实现呢。

简单的实现:

 
var heartCheck = {
    timeout: 60000,//60ms
    timeoutObj: null,
    reset: function(){
        clearTimeout(this.timeoutObj);
     this.start();
}, start: function(){ this.timeoutObj = setTimeout(function(){ ws.send("HeartBeat"); }, this.timeout) } } ws.onopen = function () { heartCheck.start(); };
ws.onmessage = function (event) {
    heartCheck.reset();
}
 

如上代码,heartCheck 的 reset和start方法主要用来控制心跳的定时。

什么条件下执行心跳:

当onopen也就是连接上时,我们便开始start计时,如果在定时时间范围内,onmessage获取到了后端的消息,我们就重置倒计时,

距离上次从后端获取到消息超过60秒之后,执行心跳检测,看是不是断连了,这个检测时间可以自己根据自身情况设定。

判断前端ws断开(断网但不限于断网的情况):

当心跳检测send方法执行之后,如果当前websocket是断开状态(或者说断网了),发送超时之后,浏览器的ws会自动触发onclose方法,重连也执行了(onclose方法体绑定了重连事件),如果当前一直是断网状态,重连会2秒(时间是自己代码设置的)执行一次直到网络正常后连接成功。

如此一来,我们判断前端主动断开ws的心跳检测就实现了。为什么说是前端主动断开,因为当前这种情况主要是通过前端ws的事件来判断的,后面说后端主动断开的情况。

 

我本想测试websocket超时时间,又发现了一些新的问题

1. 在chrome中,如果心跳检测 也就是websocket实例执行send之后,15秒内没发送到另一接收端,onclose便会执行。那么超时时间是15秒。

2. 我又打开了Firefox ,Firefox在断网7秒之后,直接执行onclose。说明在Firefox中不需要心跳检测便能自动onclose。

3.  同一代码, reconnect方法 在chrome 执行了一次,Firefox执行了两次。当然我们在几处地方(代码逻辑处和websocket事件处)绑定了reconnect(),

所以保险起见,我们还是给reconnect()方法加上一个锁,保证只执行一次

 

目前来看不同的浏览器,有不同的机制,无论浏览器websocket自身会不会在断网情况下执行onclose,加上心跳重连后,已经能保证onclose的正常触发。

 

判断后端断开:

    如果后端因为一些情况断开了ws,是可控情况下的话,会下发一个断连的消息通知,之后才会断开,我们便会重连。

如果因为一些异常断开了连接,我们是不会感应到的,所以如果我们发送了心跳一定时间之后,后端既没有返回心跳响应消息,前端又没有收到任何其他消息的话,我们就能断定后端主动断开了。

一点特别重要的发送心跳到后端,后端收到消息之后必须返回消息,否则超过60秒之后会判定后端主动断开了。再改造下代码:

 

 
var heartCheck = {
    timeout: 60000,//60ms
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function(){
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
     this.start();
    },
    start: function(){
        var self = this;
        this.timeoutObj = setTimeout(function(){
            ws.send("HeartBeat");
            self.serverTimeoutObj = setTimeout(function(){
                ws.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
            }, self.timeout)
        }, this.timeout)
    },
}

ws.onopen = function () {
   heartCheck.start();
};
ws.onmessage = function (event) {
    heartCheck.reset();
}
ws.onclose = function () {
    reconnect();
};
ws.onerror = function () {
    reconnect();
};
 
 

 

PS:

    因为目前我们这种方式会一直重连如果没连接上或者断连的话,如果有两个设备同时登陆并且会踢另一端下线,一定要发送一个踢下线的消息类型,这边接收到这种类型的消息,逻辑判断后就不再执行reconnect,否则会出现一只相互挤下线的死循环。

 

整理了一个简单的demo到github,点击查看https://github.com/zimv/WebSocketHeartBeat

 

原文链接:http://www.cnblogs.com/1wen/p/5808276.html

分享到:
评论

相关推荐

    前端开源库-robust-websocket

    1. **断线重连机制**:`robust-websocket` 包含了自动重连功能,当WebSocket连接因为网络波动、服务器重启等原因断开时,它会尝试自动恢复连接,避免因为短暂的网络问题导致整个应用的交互中断。 2. **连接状态管理...

    obs-websocket-4.8.0-Windows (1)_OBS_obs-websocket_Transition_

    【标题】"obs-websocket-4.8.0-Windows (1)_OBS_obs-websocket_Transition_" 提供的是一个OBS(Open Broadcaster Software)插件,名为“obs-websocket”并专注于过渡效果。这个插件是版本4.8.0的Windows版,它允许...

    java-WebSocket-1.3.7.jar和java-WebSocket-1.3.4.jar

    标题提到的"java-WebSocket-1.3.7.jar"和"java-WebSocket-1.3.4.jar"是这个库的两个不同版本,分别对应1.3.7和1.3.4的版本号。这两个版本的差异可能包括错误修复、性能优化、新功能的添加或API的调整。描述中提到的...

    前端开源库-home-assistant-js-websocket

    3. **错误处理**:库内置了错误处理机制,当WebSocket连接出现问题时,能够自动重连,保证了通信的稳定性。 4. **版本兼容性**:`home-assistant-js-websocket`持续更新,以保持与新版本`Home Assistant`的兼容性,...

    Android-重构Pomelo将Java-websocket替换为okhttp-websocket

    .url("wss://your-websocket-endpoint") .build(); client.newWebSocket(request, new WebSocketListener() { @Override public void onOpen(WebSocket webSocket, Response response) { // 连接打开的处理 ...

    spring-websocket-5.0.8.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-websocket-5.0.8.RELEASE.jar; 赠送原API文档:spring-websocket-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-websocket-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-...

    WebSocket.rar Android java-webSocket完整案例源码,推送,即时通信,双向通信,心跳重连

    java-webSocket是免费的,集成java-webSocket开源而成的一个比较完整的demo,实现了客户端向服务端发送消息,以及接收由服务端主动发送给客户端的消息,以及开启心跳,断连后重新连接。适用于需要双方相互主动互发...

    Spring-websocket-master.zip

    这个"Spring-websocket-master.zip"压缩包提供了一个基于Spring框架的WebSocket实时通信的示例项目,可以帮助开发者理解并实现WebSocket在实际中的应用。 首先,Spring WebSocket是Spring Framework的一部分,它...

    详解微信小程序实现WebSocket心跳重连

    最近在开发小程序用到了WebSocket,小程序提供了相应的原生API,与H5的API使用方式上有一些区别,所以流行的H5的一些成熟的类库使用起来有些困难,而原生API又存在一些缺陷,所以就自己实现了一套心跳重连机制。...

    展示tio-websocket的用法,t-io官方提供的唯一tio-websocket示范教程,包括wss和监控等高级特性

    展示tio-websocket的用法,t-io官方提供的唯一tio-websocket示范教程,包括wss和监控等高级特性

    Java-WebSocket-jar

    Java-WebSocket jar包,封装WebSocket实现。

    java-websocket jar包

    `Java-WebSocket-1.3.1-SNAPSHOT.jar` 是这个库的最新版本,SNAPSHOT标识通常表示这是一个开发中的不稳定版本,可能包含未发布的特性或修复。这个jar文件包含了所有必要的类和方法,用于创建、管理和操作WebSocket...

    spring-websocket-5.0.8.RELEASE-API文档-中文版.zip

    赠送jar包:spring-websocket-5.0.8.RELEASE.jar; 赠送原API文档:spring-websocket-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-websocket-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-...

    jboss-websocket-api_1.1_spec-2.0.0.Final-API文档-中文版.zip

    赠送jar包:jboss-websocket-api_1.1_spec-2.0.0.Final.jar; 赠送原API文档:jboss-websocket-api_1.1_spec-2.0.0.Final-javadoc.jar; 赠送源代码:jboss-websocket-api_1.1_spec-2.0.0.Final-sources.jar; 赠送...

    spring-boot-starter-websocket.zip

    在IT行业中,Spring Boot框架因其简洁的配置和强大的功能而被广泛应用。...这个压缩包提供的起步依赖简化了WebSocket在Spring Boot中的集成工作,让开发者能够专注于业务逻辑的实现,而不是底层通信细节。

    spring-websocket-4.0.0.RELEASE.jar

    spring-websocket-4.0.0.RELEASE.jar spring-websocket-4.0.0.RELEASE.jar spring-websocket-4.0.0.RELEASE.jar spring-websocket-4.0.0.RELEASE.jar

    Java-WebSocket-1.3.0.jar,Java-WebSocket-1.3.0-sources.jar

    `Java-WebSocket-1.3.0-sources.jar` 包含了库的源代码,这对于开发人员来说非常有用,因为它允许他们查看和理解库内部的工作机制,方便调试、学习和定制。如果遇到问题或需要对库进行扩展,可以直接查看源代码,...

    Python库 | gevent-websocket-0.9.4.tar.gz

    《Python库gevent-websocket深度解析》 在Python的世界里,高效的并发处理是开发者们常常面临的挑战。而gvent-websocket库就是为了解决这个问题而诞生的,它结合了gevent的协程模型和WebSocket网络协议,使得网络...

    Java-WebSocket-1.5.2.jar

    JavaWebsocket 1.5.2 jar包

    java-websocket.rar

    Java-WebSocket-1.3.5.jar Java-WebSocket-1.3.6.jar Java-WebSocket-1.3.7.jar Java-WebSocket-1.3.8.jar Java-WebSocket-1.3.9.jar Java-WebSocket-1.4.0.jar Java-WebSocket-1.4.1.jar

Global site tag (gtag.js) - Google Analytics