web-dev-qa-db-fra.com

Fermer correctement WebSocket (HTML5, Javascript)

Je joue avec HTML5 WebSockets. Je me demandais comment fermer la connexion avec grâce? Par exemple, que se passe-t-il si l'utilisateur rafraîchit la page ou ferme simplement le navigateur?

Il y a un comportement étrange lorsqu'un utilisateur actualise simplement la page sans appeler websocket.close() - lorsqu'il revient après l'actualisation, il frappe le websocket.onclose un événement.

117
Andy Hin

Selon la spécification du protocole v76 (qui est la version implémentée par le navigateur avec le support actuel):

Pour fermer la connexion proprement, une image composée d'un octet 0xFF suivi d'un octet 0x00 est envoyée par un homologue pour demander à l'autre homologue de fermer la connexion.

Si vous écrivez un serveur, vous devez vous assurer d'envoyer un cadre fermé lorsque le serveur ferme une connexion client. La méthode normale de fermeture de socket TCP) peut parfois être lente et amener les applications à penser que la connexion est toujours ouverte, même si ce n'est pas le cas.

Le navigateur devrait le faire pour vous lorsque vous fermez ou rechargez la page. Cependant, vous pouvez vous assurer qu'un cadre proche est envoyé en capturant l'événement beforeunload:

window.onbeforeunload = function() {
    websocket.onclose = function () {}; // disable onclose handler first
    websocket.close();
};

Je ne sais pas comment vous pouvez obtenir un événement onclose après l'actualisation de la page. L'objet websocket (avec le gestionnaire onclose) n'existera plus une fois la page rechargée. Si vous essayez immédiatement d’établir une connexion WebSocket sur votre page lors du chargement de la page, il se peut que vous rencontriez un problème où le serveur refuse une nouvelle connexion si peu de temps après la déconnexion de l’ancienne (ou le navigateur n’est pas prêt). établir des connexions au moment où vous essayez de vous connecter) et que vous obtenez un événement onclose pour le nouvel objet websocket.

96
kanaka

Très simple, vous le fermez :)

var myWebSocket = new WebSocket("ws://example.org"); 
myWebSocket.send("Hello Web Sockets!"); 
myWebSocket.close();

Avez-vous vérifié également le site suivant Et vérifiez le article d'introduction d'Opera

35
karlcow

Le problème est qu’il existe 2 versions principales du protocole de WebSockets actuellement utilisées. L'ancienne version qui utilise le protocole [0x00][message][0xFF], Puis la nouvelle version utilise paquets au format Hybi.

L'ancienne version du protocole est utilisée par Opera et iPod/iPad/iPhone. Il est donc important que la compatibilité avec les versions antérieures soit implémentée dans les serveurs WebSockets. Avec ces navigateurs utilisant l'ancien protocole, j'ai découvert que rafraîchir la page , ou lorsque vous quittez la page ou que vous fermez le navigateur, le navigateur ferme automatiquement la connexion.

Cependant, avec les navigateurs utilisant la nouvelle version du protocole (par exemple, Firefox, Chrome et éventuellement IE10)), la fermeture du navigateur entraîne automatiquement la fermeture de la connexion par le navigateur. Si la page ne s'affiche pas, le navigateur ne ferme pas automatiquement la connexion, mais envoie un paquet hybi au serveur dont le premier octet (l'identifiant proto) est 0x88 (mieux connu sous le nom de trame de données de fermeture) Une fois que le serveur reçoit ce paquet, il peut forcer la connexion de manière forcée, si vous le souhaitez.

34
theoobe

Comme mentionné par theoobe , certains navigateurs ne ferment pas automatiquement les websockets. N'essayez pas de gérer les événements côté client liés à une "fenêtre de navigateur proche". Il n’existe actuellement aucun moyen fiable de le faire, si vous envisagez de prendre en charge les principaux navigateurs de bureau [~ # ~] et [~ # ~] (par exemple: onbeforeunload ne fonctionnera pas dans Mobile Safari). J'ai eu une bonne expérience avec la gestion de ce problème côté serveur. Par exemple. si vous utilisez Java EE, regardez javax.websocket.Endpoint , selon le navigateur, la méthode OnClose ou le OnError la méthode sera appelée si vous fermez/rechargez la fenêtre du navigateur.

3
artkoenig

En utilisant la méthode de fermeture du socket Web, où vous pouvez écrire n'importe quelle fonction selon vos besoins.

var connection = new WebSocket('ws://127.0.0.1:1337');
    connection.onclose = () => {
            console.log('Web Socket Connection Closed');
        };
2
Akanksha Raizada