Chiudere correttamente WebSocket (HTML5, Javascript)

Sto giocando con HTML5 WebSockets. Mi stavo chiedendo, come posso chiudere la connessione con garbo? Come, cosa succede se l’utente aggiorna la pagina o semplicemente chiude il browser?

C’è un comportamento strano quando un utente si limita ad aggiornare la pagina senza chiamare websocket.close() – quando ritornano dopo l’aggiornamento colpirà l’evento websocket.onclose .

Secondo la specifica del protocollo v76 (che è la versione del browser con l’attuale strumento di supporto):

Per chiudere la connessione in modo pulito, un frame costituito da un solo byte 0xFF seguito da un byte 0x00 viene inviato da un peer per chiedere che l’altro peer chiuda la connessione.

Se stai scrivendo un server, dovresti assicurarti di inviare un frame chiuso quando il server chiude una connessione client. Il normale metodo di chiusura del socket TCP può talvolta essere lento e causare che le applicazioni ritengano che la connessione sia ancora aperta anche quando non lo è.

Il browser dovrebbe davvero fare questo per te quando chiudi o ricarichi la pagina. Tuttavia, puoi assicurarti che un frame chiuso venga inviato catturando l’evento beforeunload:

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

Non sono sicuro di come si possa ottenere un evento suclose dopo che la pagina è stata aggiornata. L’object websocket (con il gestore onclose) non esisterà più una volta ricaricata la pagina. Se stai provando immediatamente a stabilire una connessione WebSocket sulla tua pagina man mano che la pagina viene caricata, è ansible che si stia verificando un problema in cui il server rifiuta una nuova connessione così presto dopo che il vecchio si è disconnesso (o il browser non è pronto per effettuare connessioni nel punto in cui si sta tentando di connettersi) e si sta ottenendo un evento onclose per il nuovo object websocket.

Il fatto è che ci sono 2 versioni di protocollo principali di WebSockets in uso oggi. La vecchia versione che usa il protocollo [0x00][message][0xFF] , e poi c’è la nuova versione che usa i pacchetti Hybi formattati .

La vecchia versione del protocollo è utilizzata da Opera e iPod / iPad / iPhone, quindi è davvero importante che la compatibilità con le versioni precedenti sia implementata nei server WebSockets. Con questi browser che utilizzano il vecchio protocollo, ho scoperto che l’aggiornamento della pagina o l’allontanamento dalla pagina o la chiusura del browser comportano la chiusura automatica della connessione da parte del browser. Grande!!

Tuttavia, con i browser che utilizzano la nuova versione del protocollo (ad esempio Firefox, Chrome e infine IE10), solo la chiusura del browser comporterà la chiusura automatica della connessione da parte del browser. Vale a dire, se si aggiorna la pagina o si esce dalla pagina, il browser NON chiude automaticamente la connessione. Tuttavia, ciò che fa il browser, è inviare un pacchetto hybi al server con il primo byte (il proto ident) 0x88 (meglio noto come frame di dati vicino). Una volta che il server riceve questo pacchetto, può forzatamente chiudere la connessione stessa, se lo si desidera.

Molto semplice, lo chiudi 🙂

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

Hai controllato anche il seguente sito E controlla l’ articolo introduttivo di Opera

Come accennato da theoobe , alcuni browser non chiudono automaticamente le websocket. Non tentare di gestire alcun evento “Chiudi finestra browser” sul lato client. Attualmente non esiste un modo affidabile per farlo, se si considera il supporto dei principali browser desktop e mobili (ad esempio onbeforeunload non funzionerà in Mobile Safari). Ho avuto una buona esperienza con la gestione di questo problema sul lato server. Ad esempio, se si utilizza Java EE, dare un’occhiata a javax.websocket.Endpoint , in base al browser verrà chiamato il metodo OnError o il metodo OnError se si chiude / ricarica la finestra del browser.

Utilizzando il metodo close della presa Web, in cui è ansible scrivere qualsiasi funzione in base alle proprie esigenze.

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