2011-01-27 14 views
93

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?Chiusura WebSocket correttamente (HTML5, Javascript)

C'è un comportamento strano quando un utente si aggiorna semplicemente la pagina senza chiamare websocket.close() - quando ritornano dopo l'aggiornamento colpirà l'evento websocket.onclose.

risposta

70

Secondo il protocol spec V76 (che è la versione che il browser con il supporto corrente implementare) :

per chiudere la connessione in modo pulito, un telaio 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 si sta scrivendo un server, è necessario assicurarsi 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, è possibile assicurarsi una cornice stretta viene inviato facendo catturando l'evento beforeunload:

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

io non sono sicuro di come si può essere sempre un evento OnClose dopo che la pagina viene aggiornata. L'oggetto 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, è possibile 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 oggetto websocket.

+1

È possibile che in Firefox la connessione sembra bloccarsi nel carico della pagina successiva. Non riesco a trovare un riferimento ma penso che ci potrebbe essere stato un bug su questo. L'altra possibilità è che l'evento "onclose" venga attivato in modo imprevisto, o forse di proposito, mentre l'utente naviga/la pagina viene ricaricata. Ho [postato una domanda] (http://stackoverflow.com/questions/10965720/should-websocket-onclose-be-triggered-by-user-navigation-or-refresh) chiedendo quale dovrebbe essere il comportamento previsto, che browser ha ragione e come implementiamo la riconnessione automatica. – leggetter

+3

considera [questi problemi] (http://stackoverflow.com/questions/14645011/window-onbeforeunload-and-window-onunload-is-not-working-in-firefox-safari-o) con l'evento 'onbeforeunload' – artkoenig

31

Il problema è 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 utilizza i pacchetti Hybi.

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 es. Firefox, Chrome e alla fine IE10), solo la chiusura del browser si tradurrà nel browser di chiudere automaticamente la connessione. Vale a dire, se si aggiorna la pagina o si esce dalla pagina, il browser NON chiude automaticamente la connessione. Tuttavia, ciò che il browser fa, è inviare un pacchetto hybi al server con il primo byte (il proto ident) che è 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.

+3

a esempio pratico sul lato server come gestire questo pacchetto hybi? – albanx

+7

Sembra folle che non chiuda la connessione. La variabile WebSocket viene cancellata alla carica della pagina, quindi perché la connessione rimane aperta se non è possibile accedervi? Riutilizzare la connessione non avrebbe neanche senso. – Triynko

+0

@albanx controlla la mia risposta sotto – artkoenig

2

Come menzionato da theoobe, alcuni browser non chiudono automaticamente le web socket. Non tentare di gestire alcun evento "Chiudi finestra browser" sul lato client. Attualmente non esiste un modo affidabile per farlo, se consideri il supporto dei principali browser desktop E (ad esempio onbeforeunload non funzionerà in Mobile Safari). Ho avuto una buona esperienza con la gestione di questo problema sul lato server. Per esempio. se si utilizza Java EE, dare un'occhiata a javax.websocket.Endpoint, a seconda del browser verrà chiamato il metodo OnClose o il metodo OnError se si chiude/ricarica la finestra del browser.

+1

Nel mio caso, Connection si sta chiudendo durante il trasferimento dei dati, funziona bene nel caso dei browser della famiglia Opera e iOS. Per favore aiutatemi .. Sto combattendo con questo problema dalle ultime due settimane. http://stackoverflow.com/q/30799814/2225439 – Mrug

Problemi correlati