服务器在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是这样工作的:

  1. 对于k个尝试,生成0和2 ^ k-1之间的随机时间间隔,
  2. 如果能够重新连接,请将k重置为1,
  3. 如果重新连接失败,则k增加1,并在步骤1重新启动进程,
  4. 为了截断最大间隔,当达到一定次数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%。

  1. 把所有的websocket代码放在init函数中。
  2. 在onclosecallback里再次调用init。
  3. 最后调用文档就绪函数内的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(); }; }