`
iaiai
  • 浏览: 2203882 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

初探和实现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超时时间,又发现了一些新的问题
  • 在chrome中,如果心跳检测 也就是websocket实例执行send之后,15秒内没发送到另一接收端,onclose便会执行。那么超时时间是15秒。
  • 我又打开了Firefox ,Firefox在断网7秒之后,直接执行onclose。说明在Firefox中不需要心跳检测便能自动onclose。
  • 同一代码, 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();
};

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

整理了一个简单的demo到github,点击查看https://github.com/iaiai/websocket
分享到:
评论

相关推荐

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

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

    netty+websocket实现心跳和断线重连

    在本文中,我们将深入探讨如何利用 Netty 和 WebSocket 实现心跳检测和断线重连机制。 首先,我们需要理解 WebSocket 协议。WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它为客户端和服务器提供了低...

    微信小程序开发附源码:详解微信小程序实现WebSocket心跳重连.doc

    在实现心跳重连时,我们需要关注以下几个关键点: 1. **连接建立**:在小程序页面加载后,调用`wx.connectSocket`建立WebSocket连接,并在`success`回调中进行事件绑定,如示例中的`linkSocket`函数所示。 2. **...

    vue2.0 根据elementui写的WebSocket心跳和聊天重连封装

    vue2.0 根据elementui写的WebSocket心跳和聊天重连封装

    webSocket心跳检测思路及代码实现.html

    webSocket心跳检测机制及代码思想 次文章只是提供一下本人设计思路 心跳检测有很多方式可以实现在此 只是为大家提供一下思路大家一起相互学习 一起进步

    websocket封装使用心跳检测+断线重连

    websocket封装基于 1.websocket四大基础事件 2.扩展心跳检测与断线重连功能 3.核心对象封装,生成与销毁不需要客户端控制

    websocket断线重连 websocket JS框架

    如压缩包中的`websocket-heartbeat`,很可能是一个实现心跳检测的示例代码或框架。 描述中提到的"websocket的JS框架"可能是为简化WebSocket编程而设计的库,这类框架通常会提供更高级别的抽象,包括自动重连、错误...

    webSocket心跳检测设计思路及代码实现.html

    此文章主要简介一下webSocket心跳检测机制的实现思路以及代码实现,第一次发布博客如有不足之处,敬请谅解,webSocket心跳检测实现有很多方法 我只是为大家说一下我自己的实现思路

    websocket demo(java客户端,心跳监测)

    java写的websocket客户端,包含心跳监测。 此架包可解决问题:系统使用websocket 访问远程上的实时数据,但是有时候会停止更新实时数据,只要重启了自己的系统,就会继续更新数据了,此包可以完美解决此问题。

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

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

    websocket心跳检测.rar

    springboot实现websocket --已自测通过 1.心跳检测 2.掉线重连 3.前端js,前端页面

    用okhttp实现webSocket长连接

    此外,还可以根据需求实现自定义的错误处理和重试机制。 通过OkHttp实现WebSocket长连接,我们可以创建高性能、可靠的实时通信系统,为用户提供流畅的交互体验。同时,OkHttp的易用性和灵活性使得开发者能够轻松地...

    Nginx安装与使用+WebSocket集群实现及断开重连

    **Nginx安装与使用** Nginx是一款高性能的HTTP和反向代理...通过以上步骤,你可以成功地在Nginx上部署WebSocket服务,并实现集群和断线重连功能。确保在实际操作时根据自己的服务器环境和应用需求进行适当的调整。

    C语言实现的websocket

    WebSocket是一种在...综上所述,C语言实现WebSocket涉及TCP套接字编程、WebSocket协议理解和实现、以及可能的HTML辅助调试。这个过程需要深入理解网络协议和C语言编程,同时也提供了学习和实践网络编程的良好机会。

    Android 实现WebSocket长连接

    Android 实现WebSocket长连接 最近项目中引入了实时接收服务器数据的功能,考量后通过WebSocket长链接来实现。 1、建立在 TCP 协议之上,服务器端的实现比较容易。 2、与 HTTP 协议有着良好的兼容性。默认端口也是80...

    websocket心跳

    根据给定的信息,本文将详细解释“websocket心跳”的概念,并基于描述中的代码示例来解析其在前后端的实现方式...在实际开发中,还需要考虑到异常情况下的重连策略以及资源释放等问题,以确保系统的健壮性和用户体验。

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

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

    websocket 心跳连接

    ### 实现心跳检测 1. **心跳帧设计**:心跳消息可以是简单的字符串或自定义的JSON对象,只要两端能识别即可。例如,客户端发送`{'type': 'heartbeat'}`,服务器回应同样内容。 2. **心跳间隔**:心跳间隔需要根据...

    C++ 实现WebSocket 服务器

    在WebSocket服务器的实现中,gbase可能是用来处理服务器端的数据存储和查询,比如记录用户的连接信息、消息历史等。然而,没有更多的上下文,无法详细解释gbase的具体作用,这可能需要进一步的代码审查或文档查阅。 ...

Global site tag (gtag.js) - Google Analytics