107 votes

Reconnexion du client lorsque le serveur redémarre dans WebSocket

J'utilise un socket web avec PHP5 et le navigateur Chrome comme client. J'ai repris le code du site http://code.google.com/p/phpwebsocket/ .

Je lance le serveur et le client est également connecté. Je peux également chatter. Maintenant, lorsque je redémarre le serveur (en le tuant et en le redémarrant), le client reçoit les informations de déconnexion, mais ne se reconnecte pas automatiquement au serveur lorsque je le vois. client reçoit l'information de déconnexion, mais ne se reconnecte pas automatiquement au serveur lorsque j'envoie le message.

Comment y parvenir ? Par exemple, lorsque je reçois l'information de déconnexion, dois-je la vérifier et l'envoyer à JavaScript pour rafraîchir la page ou me reconnecter ?

155voto

Andrew Points 30079

Lorsque le serveur redémarre, la connexion Web Socket est fermée, de sorte que la fonction JavaScript onclose est déclenché. Voici un exemple qui tente de se reconnecter toutes les cinq secondes.

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

45voto

user2909737 Points 81

La solution proposée par Andrew ne fonctionne pas parfaitement car, en cas de perte de connexion, le serveur peut envoyer plusieurs événements de fermeture.

Dans ce cas, vous devez définir plusieurs setTimout. La solution proposée par Andrew ne peut fonctionner que si le serveur est prêt avant cinq secondes.

Ensuite, sur la base de la solution d'Andrew, retravaillée, j'ai utilisé setInterval en attachant l'ID à l'objet fenêtre (de cette façon, il est disponible "partout") :

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 */
 /* ... */
}

41voto

Joël Esponde Points 525

Reconnexion deWebSocket

Il existe une petite bibliothèque JavaScript qui décore l'API WebSocket pour fournir une connexion WebSocket qui se reconnectera automatiquement si la connexion est interrompue.

La bibliothèque minimisée avec la compression gzip est inférieure à 600 octets.

Le référentiel est disponible ici :

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

Il existe également une bibliothèque TypeScript. Il suffit de l'inclure et de remplacer new WebSocket con new ReconnectingWebSocket .

Le référentiel est disponible ici :

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

Inondation du serveur

Si un grand nombre de clients sont connectés au serveur lorsqu'il redémarre. Il peut être intéressant de gérer les délais de reconnexion des clients en utilisant un algorithme Exponential Backoff.

L'algorithme fonctionne comme suit :

  1. Pour k tentatives, générez un intervalle de temps aléatoire entre 0 et 2^k - 1,
  2. Si vous parvenez à vous reconnecter, remettez k à 1,
  3. Si la reconnexion échoue, k augmente de 1 et le processus reprend à l'étape 1,
  4. Pour tronquer l'intervalle maximal, lorsqu'un certain nombre de tentatives k a été atteint, k cesse d'augmenter après chaque tentative.

Référence :

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

ReconnectingWebSocket ne gère pas les reconnexions en utilisant cet algorithme.

34voto

complistic Points 699

J'utilise ce patten depuis un certain temps pour du JavaScript pur vanille, et il supporte un peu plus de cas que les autres réponses.

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

});

Il réessayera dès que le serveur fermera la connexion, et il vérifiera la connexion pour s'assurer qu'elle est active toutes les 5 secondes également.

Ainsi, si le serveur n'est pas opérationnel au moment de l'exécution de cette opération ou au moment de l'événement onclose, la connexion sera rétablie une fois qu'il sera de nouveau en ligne.

NOTE : L'utilisation de ce script ne vous permettra pas d'arrêter d'essayer d'ouvrir une connexion... mais je pense que c'est ce que vous voulez ?

2voto

Pradeepta Points 458

Voici les codes que j'ai utilisés dans mon projet et qui fonctionnent à 100%.

  1. Placez tout le code du websocket dans la fonction init.
  2. Dans le callback onclose, appeler à nouveau l'init.
  3. Enfin, la fonction init est appelée dans la fonction de préparation du document.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X