体彩排列五 www.8r31a.com.cn 体彩排列五 > 上网技巧 > 电脑小技巧 > websocket断线重连实践解决方案

websocket断线重连实践解决方案

时间:2018-06-25 08:56 作者:QQ地带 我要评论

最近做的在线竞答的项目需要使用websocket保持实时通讯,实现同步推题多用户在线竞答。在做过的过程中发现websocket断线频率较高,通过网上查询资料了解到nginx代理的websocket转发,无消息连接会出现超时断开问题。网上资料提到解决方案两种,一种是修改nginx配置信息,第二种是websocket发送心跳包。
下面就来总结一下本次项目中实践中解决的websocket的断线 和 重连 这两个问题的解决方案。
首先我们来看看websocket的断线问题处理,在说明这个问题之前先来说说websocket,
WebSocket是是html5开始提供的一种在单个TCP连接上进行全双工通讯协议。WebSocket用于在Web浏览器和服务器之间进行任意的双向数据传输的一种技术。
1) 创建连接: 
var ws = new websocket(url);
2) 握手成功
ws.onopen = () => {
     console.log("websocket success!");           
};
3) 监听消息推送
 ws.onmessage = (message) => {
     console.log(JSON.stringify(message));           
};
4) 监听断开连接
 ws.onclose = () => {
     console.log("websocket close!");           
};
5) 监听错误信息
ws.onerror= (err) => {
     console.log(JSON.stringify(err));           
};
主动触发包括主动断开连接,客户端主动发送消息给后端
1) 主动断开连接
ws.close();
主动断开连接,根据需要使用,基本很少用到。
2) 主动发送消息
ws.send("hello world");
针对websocket断线我们来分析一下,
断线的可能原因1:websocket超时没有消息自动断开连接,应对措施:
这时候我们就需要知道服务端设置的超时时间是多少,在小于超时时间内发送心跳包,有2中方案,一种是客户端主动发送上行心跳包,另一种方案是服务端主动发送下行心跳包。下面主要讲一下客户端也就是前端如何实现心跳包:
首先了解一下心跳包机制
 
  跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。
在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE。系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于?;罨故强梢缘?。
   心跳包一般来说都是在逻辑层发送空的echo包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。
在长连接下,有可能很长一段时间都没有数据往来。理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,?;?。
心跳检测步骤:
1客户端每隔一个时间间隔发生一个探测包给服务器
2客户端发包时启动一个超时定时器
3服务器端接收到检测包,应该回应一个包
4如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器
5如果客户端的超时定时器超时,依然没有收到应答包,则说明服务器挂了
前端解决方案:
//心跳检测
var heartCheck = {
    timeout: 30000,        //30秒发一次心跳
    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("ping");
            console.log("ping!")
            self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
                ws.close();     //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
            }, self.timeout)
        }, this.timeout)
    }
}
断线的可能原因2:websocket异常包括服务端出现中断,交互切屏等等客户端异常中断等等
针对这种异常的中断解决方案就是处理重连,下面我们给出的重连方案是使用js库处理:
引入reconnecting-websocket.min.js,ws建立链接方法使用js库api方法:
var ws = new ReconnectingWebSocket(url);
断线重连:
reconnectSocket(){
  if ('ws' in window) {
    ws = new ReconnectingWebSocket(url);
  } else if ('MozWebSocket' in window) {
    ws = new MozWebSocket(url);
  } else {
    ws = new SockJS(url);
 
  }
}
断网监测支持使用js库:offline.min.js
onLineCheck(){
  Offline.check();
  console.log(Offline.state,'---Offline.state');
  console.log(this.socketStatus,'---this.socketStatus');
  if(!this.socketStatus){
    console.log('网络连接已断开!');
    if(Offline.state === 'up' && websocket.reconnectAttempts > websocket.maxReconnectInterval){
      window.location.reload();
    }
     reconnectSocket();
  }else{
    console.log('网络连接成功!');
      websocket.send("heartBeat");
  }
}
在websocket断开链接时调用网络中断监测
websocket.onclose => () {
        onLineCheck();
 };
上面是实践过的解决方案,如果大家有更好的解决方案欢迎评论区分享交流。

标签: WebSocket
顶一下
(0)
0%
踩一下
(0)
0%

Google提供的广告

  • 云南惊现34斤重缅甸蟒  森警及时救助放生 2018-12-16
  • 李睿的专栏作者中国国家地理网 2018-12-16
  • 端午节为什么又叫女儿节? 2018-12-16
  • 山西首届百名金牌导游大赛太原选拔赛3月8日鸣锣 2018-12-15
  • 沙特承认结果很惨痛 下一场比赛必须改变 2018-12-15
  • 公安部端午节假期首日将现出行高峰 上午达峰值——人民政协网 2018-12-15
  • 十三届全国人大一次会议第三次全体会议 2018-12-14
  • 感触名家笔下的端午文化吃香粽原来可以这样文艺 2018-12-14
  • 上交所总经理蒋锋:中欧所正积极推进海尔等公司发行D股 2018-12-14
  • 博鳌亚洲论坛亚洲媒体高峰会议 2018-12-14
  • 导演贾樟柯获2018年日本福冈亚洲文化大奖 2018-12-13
  • 【新时代 新作为 新篇章】牢记嘱托 打赢脱贫攻坚战 2018-12-13
  • 韩中国文化院相关新闻 2018-12-13
  • 中国工程院院士王泽山谈用正确的“思维方法”去创新 2018-12-13
  • 云南金平上亿蝴蝶破茧而出 涧水悠悠蝴蝶翩翩 2018-12-12
  • 266| 408| 41| 243| 453| 501| 42| 270| 233| 367|