服务器在WebSocket中重新启动时重新连接客户端
我正在使用PHP5和Chrome浏览器作为客户端的Web套接字。 我已经从http://code.google.com/p/phpwebsocket/网站获取了代码。
我运行服务器,客户端也连接。 我也可以聊天。 现在,当我重新启动服务器(通过杀死它并再次启动),客户端获取断开连接的信息,但是当我发送消息时自动不与服务器重新连接。
如何做到这一点? 就像我收到断开连接的信息一样,我应该检查并将其发送到JavaScript以刷新页面或重新连接?
当服务器重新启动时,Web Socket连接closures,所以JavaScript onclose
事件被触发。 以下是一个尝试每五秒重新连接的示例。
function start(websocketServerLocation){ ws = new WebSocket(websocketServerLocation); ws.onmessage = function(evt) { alert('message received'); }; ws.onclose = function(){ // Try to reconnect in 5 seconds setTimeout(function(){start(websocketServerLocation)}, 5000); }; }
由Andrew给出的解决scheme并不完美,因为在连接丢失的情况下,服务器可能会发送几个closures事件。
在这种情况下,你会设置几个setTimout的。 Andrew提供的解决scheme只有在服务器准备就绪五秒之前才能使用。
然后,基于安德鲁解决scheme,重做,我已经使用setInterval附加到窗口对象的ID(这样就可以“无处不在”):
var timerID=0; var socket; /* Initiate what has to be done */ socket.onopen=function(event){ /* As what was before */ if(window.timerID){ /* a setInterval has been fired */ window.clearInterval(window.timerID); window.timerID=0; } /* ... */ } socket.onclose=function(event){ /* ... */ if(!window.timerID){ /* Avoid firing a new setInterval, after one has been done */ window.timerID=setInterval(function(){start(websocketServerLocation)}, 5000); } /* That way, setInterval will be fired only once after losing connection */ /* ... */ }
ReconnectingWebSocket
GitHub托pipe一个小的JavaScript库,用于装饰WebSocket API以提供一个WebSocket连接,如果连接断开,它将自动重新连接。
使用gzip压缩的缩小库小于600字节。
官方存储库在这里可用:
https://github.com/joewalnes/reconnecting-websocket
服务器泛滥
如果大量的客户端在重新启动时连接到服务器。 通过使用指数退避algorithm来pipe理客户端的重新连接时间可能是值得的。
algorithm是这样工作的:
- 对于k个尝试,生成0和2 ^ k-1之间的随机时间间隔,
- 如果能够重新连接,请将k重置为1,
- 如果重新连接失败,则k增加1,并在步骤1重新启动进程,
- 为了截断最大间隔,当达到一定次数k时,k在每次尝试后停止增加。
参考:
http://blog.johnryding.com/post/78544969349/how-to-reconnect-web-sockets-in-a-realtime-web-app
重新连接WebSocket不处理使用此algorithm重新连接。
我一直在使用这个patten一段时间的纯香草JavaScript,它支持比其他答案更多的情况。
document.addEventListener("DOMContentLoaded", function() { 'use strict'; var ws = null; function start(){ ws = new WebSocket("ws://localhost/"); ws.onopen = function(){ console.log('connected!'); }; ws.onmessage = function(e){ console.log(e.data); }; ws.onclose = function(){ console.log('closed!'); //reconnect now check(); }; } function check(){ if(!ws || ws.readyState == 3) start(); } start(); setInterval(check, 5000); });
这将在服务器closures连接后立即重试,并且将检查连接以确保每5秒钟连接一次。
因此,如果服务器在运行时或onclose事件发生时没有启动,那么连接恢复联机后仍会恢复。
注:使用这个脚本不会让你永远停止尝试打开连接…但我认为这就是你想要的?
以下是我在我的项目中使用的代码,工作100%。
- 把所有的websocket代码放在init函数中。
- 在onclosecallback里再次调用init。
- 最后调用文档就绪函数内的init函数。
var name = sessionStorage.getItem('name');
wsUri = "ws://localhost:8080"; var websocket; $(function() { init(); $("#chat_text_box").on("keypress", function(e) { if (e.keyCode == 13) { //For Enter Button e.preventDefault(); var mymessage = $('#chat_text_box').val(); if(mymessage){ var msg = { type: 'chat_text', data : { name:name, msg:mymessage } }; console.log(msg); websocket.send(JSON.stringify(msg)); $('#chat_text_box').val(''); } return false; } }); }); function init() { websocket = new WebSocket(wsUri); websocket.onopen = function(ev) { /*connection is open */ } websocket.onmessage = function(ev) { var data = JSON.parse(ev.data); //PHP sends Json data var type = data.type;//alert(JSON.stringify(data)); switch(type) { case "chat_text": var text = "<div><span class='user'>"+data.data.sender_name+" : </span><span class='msg'>"+data.data.msg+"</span></div>"; $('#chat-messages').append(text); break; default: break; } }; websocket.onerror = function(ev){}; websocket.onclose = function(ev) { init(); }; }