web-dev-qa-db-fra.com

Comment se reconnecter à websocket après une connexion étroite

Je construis ma connexion websocket avec ce code (par exemple):

var socket = new WebSocket("ws://94.12.176.177:8080");

Et je ferme la connexion avec celui-ci:

socket.close();

Mais comment puis-je rétablir la connexion?

J'ai fait quelques recherches et essayé plusieurs méthodes. Cette question n'a pas pu m'aider: Socket.io se reconnecter à la déconnexion? C'est le seul résultat qui se rapproche de ce que je recherche.

La raison pour laquelle je veux le faire est de permettre aux utilisateurs de cesser d'envoyer temporairement des données sur le Web et de les renvoyer après un certain temps. Sans reconnexion, l'utilisateur doit actualiser la page pour renvoyer. Cela peut entraîner la perte de certaines données. Merci.

40
ket

Vous devrez recréer le socket afin de le reconnecter. Le seul problème avec cela est que vous devrez rattacher vos gestionnaires.

Mais vraiment, les websockets sont conçues pour rester ouvertes.

Une meilleure méthode serait d'avoir le serveur ferme la connexion. De cette façon, le websocket déclenchera un événement onclose mais continuera à tenter d'établir la connexion. Lorsque le serveur réécoute, la connexion est automatiquement rétablie.

14
Jivings

Lorsque le serveur ferme la connexion, le client n'essaye pas de se reconnecter. Avec certains frameworks JS peut-être, mais la question était, au moment de cette réponse, marquée comme un simple Vanilla JS.

Je suis un peu frustré parce que la réponse acceptée et votée est clairement erronée, et cela m'a coûté un peu plus de temps pour trouver la bonne solution.

Qui est ici: Reconnexion du client lorsque le serveur redémarre dans WebSocket

64
SzG

J'ai trouvé la meilleure solution sur cette page: sam-low.com

Une fois la connexion d'origine fermée, vous devez créer un nouvel objet WebSocket avec de nouveaux écouteurs d'événements

function startWebsocket() {
  var ws = new WebSocket('ws://localhost:8080')

  ws.onmessage = function(e){
    console.log('websocket message event:', e)
  }

  ws.onclose = function(){
    // connection closed, discard old websocket and create a new one in 5s
    ws = null
    setTimeout(startWebsocket, 5000)
  }
}

startWebsocket();

Notez que s'il y a un problème de reconnexion, le nouvel objet WebSocket recevra toujours un autre événement de fermeture, ce qui signifie que onclose() sera exécuté même s'il ne s'est jamais ouvert techniquement. C'est pourquoi le délai de cinq secondes est raisonnable - sans cela, vous pourriez vous retrouver à créer et à détruire des milliers de connexions Websocket à un rythme qui casserait probablement quelque chose.

5
Pol

Une mise en œuvre sans faille:

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

Pour le tester:

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

Edit: Prenez note de l'implémentation de la suppression exponentielle (au niveau du thread lié par le commentaire principal: https://stackoverflow.com/a/37038217/880542 ), pas dans le code ci-dessus MAIS TRÈS TRÈS CRUCIAL.

Modifier à nouveau: consultez back de primus: https://www.npmjs.com/package/back , c'est une implémentation sexy flexible.

3
xemasiv