Me gustaría obtener la razón por la que se cerraron los websockets, para poder mostrar el mensaje correcto al usuario.
yo tengo
sok.onerror=function (evt)
{//since there is an error, sockets will close so...
sok.onclose=function(e){
console.log("WebSocket Error: " , e);}
El código es siempre 1006 y el motivo siempre es "". Pero quiero distinguir diferentes razones de cierre.
Por ejemplo, la línea de comando da una razón de error: "no puedes borrar eso, porque la base de datos no te lo permite". Pero en la consola de Chrome, la razón sigue siendo "".
¿Alguna otra forma de diferenciar las diferentes razones de cierre?
javascript
websocket
slevin
fuente
fuente
Respuestas:
El código de cierre
1006
es un código especial que significa que la implementación del navegador cerró la conexión de forma anormal (localmente).Si el cliente de su navegador informa un código de cierre
1006
, entonces debería estar mirando elwebsocket.onerror(evt)
evento para obtener más detalles.Sin embargo, Chrome rara vez informará sobre
1006
razones de código cerrado al lado de Javascript. Es probable que esto se deba a las reglas de seguridad del cliente en la especificación de WebSocket para evitar el abuso de WebSocket. (como usarlo para buscar puertos abiertos en un servidor de destino o para generar muchas conexiones para un ataque de denegación de servicio).Tenga en cuenta que Chrome a menudo informará un código de cierre
1006
si hay un error durante la actualización HTTP a Websocket (este es el paso antes de que un WebSocket esté técnicamente "conectado"). Por razones como una autenticación o autorización incorrecta, o un uso incorrecto del protocolo (como solicitar un subprotocolo, pero el servidor en sí no admite ese mismo subprotocolo), o incluso un intento de hablar con una ubicación de servidor que no es un WebSocket ( como intentar conectarse aws://images.google.com/
)Básicamente, si ve un código de cierre
1006
, tiene un error de nivel muy bajo con el propio WebSocket (similar a "No se puede abrir el archivo" o "Error de socket"), que en realidad no está destinado al usuario, ya que apunta a un problema de nivel bajo. con su código e implementación. Solucione sus problemas de bajo nivel y, cuando esté conectado, podrá incluir códigos de error más razonables. Puede lograr esto en términos de alcance o severidad en su proyecto. Ejemplo: la información y el nivel de advertencia son parte del protocolo específico de su proyecto y no provocan la terminación de la conexión. Con informes de mensajes graves o fatales, también utilice el protocolo de su proyecto para transmitir tantos detalles como desee y luego cierre la conexión utilizando las capacidades limitadas del flujo de cierre de WebSocket.Tenga en cuenta que los códigos de cierre de WebSocket están definidos de forma muy estricta, y la frase / mensaje de motivo de cierre no puede superar los 123 caracteres de longitud (esta es una limitación intencionada de WebSocket).
Pero no todo está perdido, si solo desea esta información por razones de depuración, el detalle del cierre y su razón subyacente a menudo se informa con una buena cantidad de detalles en la consola Javascript de Chrome.
fuente
sok.onerror=function (evt) {console.log(evt);}
los detalles no son tanto. Ni siquiera unareason
o algo. Entonces, ¿no hay opciones en absoluto? Solo le muestro al usuario,something is wrong, or not connencted?
No tan fácil de usar, sería bueno si el usuario pudiera ver "No se puede eliminar, debido a restricciones en la base de datos". ¿Alguna opción? Graciassok.onclose
lugar, debe usar qué desencadenadoresclose event
, tienereason
ycode
en élsok.onclose
funcionará para muchos caminos, pero no para todos. Especialmente mal protocolo, errores de apretón de manos incorrectos (como algunas condiciones que podrían causar código de cierre1006
). ¿Cambiará esto en el futuro? Probablemente. Pero cuando se escribió esta respuesta, era verdad.reason
regresado cuando usóonerror
Me estaba señalando que estas propiedadescode
yreason
específica aclose
evento noerror
evento. así que sería mejor para él usaronclose
en su lugar, ¿me estoy perdiendo algo?1006
que tiene un significado especial y un manejo especial en la especificación websocket y la api websocket javascript. La razón por la que la cadena / mensaje en algunas1006
condiciones no se expone de manera específica e intencional en ninguna parte de la API. (como señaló la respuesta). Esto no es un error en la API, se trata simplemente de abordar las diversas especificaciones y sus preocupaciones sobre el abuso de websocket para fines que no sean de websocket.En mi caso, y posiblemente en el de @BIOHAZARD, lo fue
nginx proxy timeout
. De forma predeterminada, es un60
segundo sin actividad en el socketLo cambié a 24 horas
nginx
y resolvió el problema.proxy_read_timeout 86400s; proxy_send_timeout 86400s;
fuente
Parece que este es el caso cuando Chrome no cumple con el estándar WebSocket. Cuando el servidor inicia el cierre y envía un marco de cierre a un cliente, Chrome considera que esto es un error y lo informa al lado de JS con el código 1006 y sin mensaje de motivo. En mis pruebas, Chrome nunca responde a los marcos cerrados iniciados por el servidor (código de cierre 1000), lo que sugiere que el código 1006 probablemente significa que Chrome está informando su propio error interno.
PS Firefox v57.00 maneja este caso correctamente y entrega con éxito el mensaje del motivo del servidor al lado de JS.
fuente
Pensé que esto podría ser útil para otros. Saber que la expresión regular es útil, niños. Permanece en la escuela.
Editar: ¡Lo convirtió en una función práctica y elegante!
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)'; }
Uso:
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' }
Fuente (con ediciones menores para la concisión): https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
fuente
Tengo el error al usar Chrome como cliente y golang gorilla websocket como servidor bajo el proxy nginx
Y enviar un mensaje de "ping" del servidor al cliente cada x segundo problema resuelto
fuente
Esta puede ser la URL de su websocket que está utilizando en el dispositivo que no es la misma (está presionando una URL de websocket diferente desde el dispositivo android / iphone)
fuente