Chciałbym poznać powód zamknięcia websockets, żeby pokazać użytkownikowi właściwą wiadomość.
mam
sok.onerror=function (evt)
{//since there is an error, sockets will close so...
sok.onclose=function(e){
console.log("WebSocket Error: " , e);}
Kod to zawsze 1006, a powodem jest zawsze „”. Ale chcę rozróżnić różne powody zamknięcia.
Na przykład wiersz poleceń podaje przyczynę błędu: „nie można tego usunąć, ponieważ baza danych na to nie pozwala”. Ale na konsoli Chrome przyczyną jest nadal „”.
Czy jest jakiś inny sposób na odróżnienie różnych powodów zamknięcia?
javascript
websocket
slevin
źródło
źródło
Odpowiedzi:
Kod zamknięcia
1006
to specjalny kod, który oznacza, że połączenie zostało zamknięte nieprawidłowo (lokalnie) przez implementację przeglądarki.Jeśli klient przeglądarki zgłasza kod zamknięcia
1006
, należy przyjrzeć sięwebsocket.onerror(evt)
zdarzeniu, aby uzyskać szczegółowe informacje.Jednak Chrome rzadko zgłasza
1006
przyczyny zamknięcia kodu po stronie JavaScript. Jest to prawdopodobnie spowodowane regułami bezpieczeństwa klienta w specyfikacji protokołu WebSocket, aby zapobiec nadużywaniu protokołu WebSocket. (np. używanie go do skanowania w poszukiwaniu otwartych portów na serwerze docelowym lub do generowania wielu połączeń w przypadku ataku typu „odmowa usługi”).Pamiętaj, że Chrome często zgłasza kod zamknięcia,
1006
jeśli wystąpi błąd podczas uaktualniania HTTP do Websocket (jest to krok przed technicznym „połączeniem” WebSocket). Z powodów takich jak złe uwierzytelnienie lub autoryzacja lub złe użycie protokołu (na przykład żądanie podprotokołu, ale sam serwer nie obsługuje tego samego podprotokołu), a nawet próba nawiązania połączenia z lokalizacją serwera, która nie jest protokołem WebSocket ( takie jak próba połączenia sięws://images.google.com/
)Zasadniczo, jeśli widzisz kod zamknięcia
1006
, masz bardzo niski poziom błędu z samym WebSocket (podobny do „Unable to Open File” lub „Socket Error”), który nie jest przeznaczony dla użytkownika, ponieważ wskazuje na problem niskiego poziomu swoim kodem i implementacją. Rozwiąż problemy niskiego poziomu, a po uzyskaniu połączenia możesz dołączyć bardziej rozsądne kody błędów. Możesz to osiągnąć pod względem zakresu lub wagi projektu. Przykład: poziom informacji i ostrzeżenia są częścią specyficznego protokołu twojego projektu i nie powodują przerwania połączenia. Z poważnymi lub krytycznymi wiadomościami zgłaszaj również przy użyciu protokołu projektu, aby przekazać tyle szczegółów, ile chcesz, a następnie zamykając połączenie przy użyciu ograniczonych możliwości przepływu zamkniętego WebSocket.Należy pamiętać, że kody zamykające WebSocket są bardzo ściśle zdefiniowane, a fraza / komunikat powodu zamknięcia nie może przekraczać 123 znaków (jest to celowe ograniczenie WebSocket).
Ale nie wszystko jest stracone, jeśli potrzebujesz tych informacji tylko z powodów debugowania, szczegóły zamknięcia i jego podstawowa przyczyna są często zgłaszane z dużą ilością szczegółów w konsoli JavaScript Chrome.
źródło
sok.onerror=function (evt) {console.log(evt);}
szczegółów, to nie jest tak dużo. Ani nawetreason
czy coś. Więc nie ma żadnych opcji? Po prostu pokazuję użytkownikowi, żesomething is wrong, or not connencted?
nie jest zbyt przyjazny dla użytkownika, byłoby miło, gdyby użytkownik widział „Nie można usunąć, przyczyna ograniczeń bazy danych”. Jakieś opcje? Dziękisok.onclose
zamiast tego użyć tego, który wyzwalaclose event
, mareason
iwcode
nimsok.onclose
będzie działać na wielu ścieżkach, ale nie na wszystkich. Szczególnie zły protokół, złe błędy uzgadniania (jak niektóre warunki, które mogą powodować zamknięcie kodu1006
). Czy to się zmieni w przyszłości? Prawdopodobnie. Ale kiedy napisano tę odpowiedź, była to prawda.reason
wróciło, kiedy użył Wskazałem,onerror
że te właściwościcode
ireason
specyficzne dlaclose
wydarzenia, a nieerror
zdarzenia. więc lepiej byłoby dla niego użyćonclose
zamiast tego, czy coś mi brakuje?1006
który ma specjalne znaczenie, i specjalnej obsługi w specyfikacji Websocket oraz JavaScript websocket api. Powód / komunikat w pewnych1006
warunkach nie jest specjalnie i celowo ujawniany nigdzie w API. (jak wskazała odpowiedź). To nie jest błąd w API, a jedynie zajęcie się różnymi specyfikacjami i ich obawami dotyczącymi nadużywania WebSocket do celów innych niż WebSocket.W moim i prawdopodobnie @BIOHAZARD przypadku tak było
nginx proxy timeout
. Domyślnie jest to60
sekunda bez aktywności w gnieździeZmieniłem to na 24h
nginx
i rozwiązałem problemproxy_read_timeout 86400s; proxy_send_timeout 86400s;
źródło
Wygląda na to, że tak jest w przypadku, gdy Chrome nie jest zgodny ze standardem WebSocket. Gdy serwer inicjuje zamknięcie i wysyła ramkę do klienta, Chrome traktuje to jako błąd i zgłasza to stronie JS z kodem 1006 i bez komunikatu o przyczynie. W moich testach Chrome nigdy nie reaguje na zamknięte ramki inicjowane przez serwer (kod zamykający 1000), co sugeruje, że kod 1006 prawdopodobnie oznacza, że Chrome zgłasza własny błąd wewnętrzny.
PS Firefox v57.00 prawidłowo obsługuje ten przypadek i pomyślnie dostarcza komunikat powodujący serwer po stronie JS.
źródło
Pomyślałem, że to może być przydatne dla innych. Znajomość wyrażeń regularnych jest przydatna, dzieciaki. Zostań w szkole.
Edycja: zamieniono go w poręczną funkcję dandysa!
let specificStatusCodeMappings = { '1000': 'Normal Closure', '1001': 'Going Away', '1002': 'Protocol Error', '1003': 'Unsupported Data', '1004': '(For future)', '1005': 'No Status Received', '1006': 'Abnormal Closure', '1007': 'Invalid frame payload data', '1008': 'Policy Violation', '1009': 'Message too big', '1010': 'Missing Extension', '1011': 'Internal Error', '1012': 'Service Restart', '1013': 'Try Again Later', '1014': 'Bad Gateway', '1015': 'TLS Handshake' }; function getStatusCodeString(code) { if (code >= 0 && code <= 999) { return '(Unused)'; } else if (code >= 1016) { if (code <= 1999) { return '(For WebSocket standard)'; } else if (code <= 2999) { return '(For WebSocket extensions)'; } else if (code <= 3999) { return '(For libraries and frameworks)'; } else if (code <= 4999) { return '(For applications)'; } } if (typeof(specificStatusCodeMappings[code]) !== 'undefined') { return specificStatusCodeMappings[code]; } return '(Unknown)'; }
Stosowanie:
getStatusCodeString(1006); //'Abnormal Closure'
{ '0-999': '(Unused)', '1016-1999': '(For WebSocket standard)', '2000-2999': '(For WebSocket extensions)', '3000-3999': '(For libraries and frameworks)', '4000-4999': '(For applications)' } { '1000': 'Normal Closure', '1001': 'Going Away', '1002': 'Protocol Error', '1003': 'Unsupported Data', '1004': '(For future)', '1005': 'No Status Received', '1006': 'Abnormal Closure', '1007': 'Invalid frame payload data', '1008': 'Policy Violation', '1009': 'Message too big', '1010': 'Missing Extension', '1011': 'Internal Error', '1012': 'Service Restart', '1013': 'Try Again Later', '1014': 'Bad Gateway', '1015': 'TLS Handshake' }
Źródło (z drobnymi zmianami dla zwięzłości): https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
źródło
Wystąpił błąd podczas używania Chrome jako klienta i golang gorilla websocket jako serwera pod proxy Nginx
Wysyłanie co x sekund tylko wiadomości „ping” z serwera do klienta rozwiązało problem
źródło
To może być Twój adres URL Websocket, którego używasz w urządzeniu, nie jest taki sam (trafiasz na inny adres URL Websocket z Android / iphonedevice)
źródło