Переподключение клиента при перезагрузке сервера в WebSocket


Я использую веб-сокет, используя PHP5 и браузер Chrome в качестве клиента. Я взял код с сайта http://code.google.com/p/phpwebsocket/.

Я запускаю сервер, и клиент также подключен. Я тоже могу поболтать. Теперь, когда я перезапускаю сервер (убив его и запустив его снова), клиент получает отключенную информацию, но автоматически не подключается к серверу при отправке сообщения.

Как этого добиться? Например, когда я получите информацию о Dis-connected, должен ли я проверить ее и отправить в JavaScript для обновления страницы или повторного подключения?

6 65

6 ответов:

когда сервер перезагружается, соединение с веб-сокетом закрывается, поэтому 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);
    };
}

решение, данное Андреем, не работает идеально, потому что в случае потери соединения сервер может отправить несколько близких событий.

в этом случае вы установите несколько settimout'S. решение, данное Эндрю, может работать только в том случае, если сервер готов до пяти секунд.

затем, основываясь на решении Эндрю, переработанном, я использовал setInterval, прикрепляющий идентификатор к объекту окна (таким образом, он доступен "везде"):

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 размещена небольшая библиотека JavaScript, которая украшает API WebSocket, чтобы обеспечить подключение WebSocket, которое будет автоматически повторно подключаться, если соединение будет удалено.

уменьшенная библиотека с сжатием gzip составляет менее 600 байт.

официальный репозиторий доступен здесь:

https://github.com/joewalnes/reconnecting-websocket

сервер потока

Если a при перезагрузке к серверу подключается большое количество клиентов. Возможно, стоит управлять таймингами повторного подключения клиентов с помощью экспоненциального алгоритма обратного отсчета.

алгоритм работает следующим образом:

  1. для K попыток сгенерируйте случайный интервал времени между 0 и 2^k-1,
  2. если вы можете снова подключиться, сбросьте k до 1,
  3. если повторное подключение не удается, k увеличивается на 1 и процесс перезапускается на шаге 1,
  4. для усечения максимального интервала, когда достигнуто определенное количество попыток k, k перестает увеличиваться после каждой попытки.

Référence:

http://blog.johnryding.com/post/78544969349/how-to-reconnect-web-sockets-in-a-realtime-web-app

ReconnectingWebSocket не обрабатывает повторные подключения с помощью этого алгоритма.

Я использую этот Паттен некоторое время для чистого ванильного 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);


});

это повторится, как только сервер закроет соединение, и он будет проверять соединение, чтобы убедиться, что оно также работает каждые 5 секунд.

поэтому, если сервер не работает, когда это выполняется или во время события onclose соединение все равно вернется, как только оно вернется в сеть.

Примечание: используя это скрипт не позволит вам когда-либо прекратить попытки открыть соединение... но я думаю, что это то, что вы хотите?

Ниже приведены коды, которые я использовал в своем проекте, который работает на 100%.

  1. поместите весь код websocket внутри функции init.
  2. внутри метод onclose обратного вызова, повторный вызов метода init.
  3. наконец, вызовите функцию init внутри функции готовности документа.

var name = sessionStorage.getItem ('имя');

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();   };  
}

Не могу комментировать, но следующее:

var socket;

const socketMessageListener = (event) => {
  console.log(event.data);
};

const socketOpenListener = (event) => {
  console.log('Connected');
  socket.send('hello');
};

const socketCloseListener = (event) => {
  if (socket) {
    console.error('Disconnected.');
  }
  socket = new WebSocket('ws://localhost:8080');
  socket.addEventListener('open', socketOpenListener);
  socket.addEventListener('message', socketMessageListener);
  socket.addEventListener('close', socketCloseListener);
};

socketCloseListener();

// for testing
setTimeout(()=>{
  socket.close();
},5000);

плюс https://www.npmjs.com/package/back уже достаточно хорошо:)