- 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", "beat");
- }, this.timeout)
- }
- }
- ws.onopen = function () {
- heartCheck.start();
- };
- ws.onmessage = function (event) {
- heartCheck.reset();
- }
如上代码,heartCheck 的 reset和start方法主要用来控制心跳的定时。
当onopen也就是连接上时,我们便开始start计时,如果在定时时间范围内,onmessage获取到了服务器的消息,我们就重置倒计时,
所以在距离上次从服务器获取到消息,闲置60秒之后我们才会心跳检测,这个检测时间可以自己根据自身情况设定。
当心跳检测send执行之后,如果当前websocket是断开状态,发送超时之后,onclose方法便会被执行,重连也执行了。
如此一来,我们的心跳检测就实现了。
后来,我本想测试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的正常触发。