Я хотел бы выяснить причину закрытия веб-сокетов, чтобы я мог показать правильное сообщение пользователю.
у меня есть
sok.onerror=function (evt)
{//since there is an error, sockets will close so...
sok.onclose=function(e){
console.log("WebSocket Error: " , e);}
Код всегда 1006 и причина всегда "". Но я хочу выделить разные заключительные причины.
Например, в командной строке указывается причина ошибки: «вы не можете удалить это, потому что база данных не позволит вам». Но на консоли Chrome причина по-прежнему "".
Есть ли другой способ отличить разные причины закрытия?
javascript
websocket
Slevin
источник
источник
Ответы:
Код
1006
закрытия - это специальный код, который означает, что соединение было закрыто ненормально (локально) реализацией браузера.Если ваш браузер-клиент сообщает о закрытом коде
1006
, вам следует изучитьwebsocket.onerror(evt)
событие, чтобы узнать подробности.Однако Chrome редко сообщает о
1006
причинах закрытия кода на стороне Javascript. Вероятно, это связано с правилами безопасности клиента в спецификации WebSocket для предотвращения злоупотребления WebSocket. (например, его использование для сканирования открытых портов на целевом сервере или для создания большого количества соединений для атаки типа «отказ в обслуживании»).Обратите внимание, что Chrome часто сообщает о
1006
закрытом коде, если во время HTTP-обновления до Websocket возникает ошибка (это шаг перед технически «подключением» WebSocket). По таким причинам, как неправильная аутентификация или авторизация, или неправильное использование протокола (например, запрос подпротокола, но сам сервер не поддерживает тот же подпротокол), или даже попытка поговорить с расположением сервера, которое не является WebSocket ( например, попытка подключиться кws://images.google.com/
)По сути, если вы видите закрытый код
1006
, у вас есть ошибка очень низкого уровня с самим WebSocket (похожая на «Невозможно открыть файл» или «Ошибка сокета»), не предназначенная для пользователя, поскольку указывает на проблему низкого уровня. с вашим кодом и реализацией. Устраните проблемы низкого уровня, а затем, когда вы подключитесь, вы можете включить более разумные коды ошибок. Вы можете добиться этого с точки зрения масштаба или серьезности вашего проекта. Пример: информация и уровень предупреждений являются частью конкретного протокола вашего проекта и не приводят к разрыву соединения. При создании отчетов о серьезных или фатальных сообщениях также используется протокол вашего проекта, чтобы передать столько деталей, сколько вы хотите, а затем закрывать соединение, используя ограниченные возможности потока закрытия WebSocket.Имейте в виду, что коды закрытия WebSocket очень строго определены, а длина фразы / сообщения причины закрытия не может превышать 123 символа (это намеренное ограничение WebSocket).
Но не все потеряно, если вам просто нужна эта информация для отладки, подробности закрытия и его основная причина часто сообщаются с достаточным количеством деталей в консоли Javascript Chrome.
источник
sok.onerror=function (evt) {console.log(evt);}
то деталей не так уж и много. Дажеreason
ни чего. Значит, вариантов вообще нет? Я просто показываю пользователю, что этоsomething is wrong, or not connencted?
не так удобно, было бы неплохо, если бы пользователь увидел «Вы не можете удалить, из-за ограничений базы данных». Есть варианты? Спасибоsok.onclose
Вместо этого вы должны использовать триггерыclose event
, которые естьreason
иcode
в немsok.onclose
будет работать для многих путей, но не для всех. Особенно плохой протокол, плохие ошибки рукопожатия (например, некоторые условия, которые могут вызвать закрытие кода1006
). Изменится ли это в будущем? Наверное. Но когда был написан этот ответ, это было правдой.reason
вернулся, когда он использовал,onerror
я указывал, что эти свойстваcode
иreason
относятся кclose
событию, а не кerror
событию. так что было бы лучше для него , чтобы использоватьonclose
вместо этого, я что - то отсутствует?1006
который имеет особое значение, и специальной обработке в спецификации веб-сокета и javascript websocket api. Строка / сообщение причины при некоторых1006
условиях специально и намеренно не отображаются нигде в API. (как указано в ответе). Это не ошибка API, это просто решение различных спецификаций и их озабоченность по поводу злоупотребления веб-сокетом для целей, не связанных с веб-сокетом.В моем случае и, возможно, в случае @BIOHAZARD это было так
nginx proxy timeout
. По умолчанию это60
sec без активности в сокетеЯ изменил его на 24 часа
nginx
и решил проблему.proxy_read_timeout 86400s; proxy_send_timeout 86400s;
источник
Похоже, это тот случай, когда Chrome не совместим со стандартом WebSocket. Когда сервер инициирует закрытие и отправляет клиенту кадр закрытия, Chrome считает это ошибкой и сообщает об этом стороне JS с кодом 1006 без сообщения о причине. В моих тестах Chrome никогда не реагирует на инициированные сервером кадры закрытия (код закрытия 1000), предполагая, что код 1006, вероятно, означает, что Chrome сообщает о собственной внутренней ошибке.
PS Firefox v57.00 правильно обрабатывает этот случай и успешно доставляет сообщение о причине сервера на сторону JS.
источник
Думал, что это может быть полезно для других. Знать регулярное выражение полезно, дети. Останься в школе.
Изменить: превратили его в удобную функцию денди!
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)'; }
Применение:
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' }
Источник (с небольшими правками для краткости): https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
источник
У меня возникла ошибка при использовании Chrome в качестве клиента и golang gorilla websocket в качестве сервера под прокси-сервером nginx
И отправка лишь некоторого "ping" сообщения от сервера к клиенту каждые x секунд решает проблему.
источник
Это может быть ваш URL-адрес веб-сокета, который вы используете на устройстве, не тот же (вы нажимаете другой URL-адрес веб-сокета из android / iphonedevice)
источник