Zgodnie ze specyfikacją protokołu v76 (która jest wersją przeglądarki z obecną obsługą implementacji):
Aby czysto zamknąć połączenie, ramka składająca się tylko z bajtu 0xFF, po którym następuje bajt 0x00, jest wysyłana od jednego peera z prośbą o zamknięcie połączenia przez drugiego peera.
Jeśli piszesz na serwerze, powinieneś upewnić się, że wysyłasz bliską ramkę, gdy serwer zamyka połączenie klienta. Normalna metoda zamykania gniazda TCP może czasami być powolna i powodować, że aplikacje myślą, że połączenie jest nadal otwarte, nawet jeśli nie jest.
Przeglądarka powinna naprawdę zrobić to za Ciebie po zamknięciu lub ponownym załadowaniu strony. Możesz jednak upewnić się, że zostanie wysłana zamknięta ramka, przechwytując zdarzenie beforeunload:
window.onbeforeunload = function() {
websocket.onclose = function () {}; // disable onclose handler first
websocket.close();
};
Nie wiem, jak można uzyskać zdarzenie onclose po odświeżeniu strony. Obiekt websocket (z obsługą onclose) nie będzie już istniał po ponownym załadowaniu strony. Jeśli od razu próbujesz nawiązać połączenie WebSocket na swojej stronie podczas ładowania strony, możesz napotkać problem polegający na tym, że serwer odmawia nowego połączenia tak szybko, jak stary się rozłączył (lub przeglądarka nie jest gotowa aby nawiązać połączenia w punkcie, w którym próbujesz się połączyć) i otrzymujesz zdarzenie onclose dla nowego obiektu websocket.
onclose
zdarzenie jest wywoływane nieoczekiwanie lub celowo, gdy użytkownik nawiguje / strona jest ponownie ładowana. Mam napisali pytanie pytaniem, co oczekiwane zachowanie powinno być, co przeglądarka ma rację i jak wdrożyć automatycznie połączy.onbeforeunload
wydarzeniemBardzo proste, zamykasz :)
Czy sprawdziłeś również następującą stronę i zapoznałeś się z artykułem wprowadzającym do Opery
źródło
Chodzi o to, że obecnie używane są 2 główne wersje protokołu WebSockets. Stara wersja korzystająca z
[0x00][message][0xFF]
protokołu, a także nowa wersja korzystająca z pakietów sformatowanych w Hybi .Stara wersja protokołu jest używana przez Operę i iPoda / iPada / iPhony, więc tak naprawdę ważne jest, aby na serwerach WebSockets zaimplementowano kompatybilność wsteczną. W przypadku tych przeglądarek korzystających ze starego protokołu odkryłem, że odświeżenie strony, opuszczenie strony lub zamknięcie przeglądarki powoduje automatyczne zamknięcie połączenia przez przeglądarkę. Wspaniały!!
Jednak w przypadku przeglądarek korzystających z nowej wersji protokołu (np. Firefox, Chrome i ewentualnie IE10), dopiero zamknięcie przeglądarki spowoduje automatyczne zamknięcie połączenia. Oznacza to, że jeśli odświeżysz stronę lub opuścisz stronę, przeglądarka NIE zamknie automatycznie połączenia. Jednak przeglądarka wysyła pakiet hybi do serwera z pierwszym bajtem (proto ident)
0x88
(lepiej znanym jako zamknięta ramka danych). Gdy serwer odbierze ten pakiet, może wymusić samo zamknięcie połączenia, jeśli tak zdecydujesz.źródło
Jak wspomniał theoobe , niektóre przeglądarki nie zamykają gniazd sieciowych automatycznie. Nie próbuj obsługiwać żadnych zdarzeń „zamknięcia okna przeglądarki” po stronie klienta. Obecnie nie ma niezawodnego sposobu, aby to zrobić, jeśli weźmiesz pod uwagę obsługę głównych przeglądarek stacjonarnych i mobilnych (np.
onbeforeunload
Nie będzie działać w Mobile Safari). Miałem dobre doświadczenia z obsługą tego problemu po stronie serwera. Np. Jeśli używasz Java EE, spójrz na javax.websocket.Endpoint , w zależności od przeglądarkiOnClose
metoda lubOnError
metoda zostanie wywołana po zamknięciu / przeładowaniu okna przeglądarki.źródło
Używając zamkniętej metody gniazda sieciowego, możesz napisać dowolną funkcję zgodnie z wymaganiami.
źródło