Eu gostaria de obter o motivo do fechamento dos websockets, para que eu possa mostrar a mensagem certa ao usuário.
eu tenho
sok.onerror=function (evt)
{//since there is an error, sockets will close so...
sok.onclose=function(e){
console.log("WebSocket Error: " , e);}
O código é sempre 1006 e o motivo é sempre "". Mas eu quero diferenciar os diferentes motivos de fechamento.
Por exemplo, a linha de comando fornece um motivo de erro: "você não pode excluir isso, porque o banco de dados não permite". Mas no console do Chrome, o motivo ainda é "".
Existe alguma outra maneira de diferenciar os diferentes motivos de fechamento?
javascript
websocket
Slevin
fonte
fonte
Respostas:
Close Code
1006
é um código especial que significa que a conexão foi fechada de forma anormal (localmente) pela implementação do navegador.Se o seu cliente de navegador relatar código de fechamento
1006
, você deve examinar owebsocket.onerror(evt)
evento para obter detalhes.No entanto, o Chrome raramente relatará quaisquer
1006
motivos de fechamento de código para o lado do Javascript. Provavelmente, isso se deve às regras de segurança do cliente nas especificações do WebSocket para evitar o abuso do WebSocket. (como usá-lo para verificar portas abertas em um servidor de destino ou para gerar muitas conexões para um ataque de negação de serviço).Observe que o Chrome frequentemente relatará um código de fechamento
1006
se houver um erro durante a atualização HTTP para o Websocket (esta é a etapa antes de um WebSocket ser tecnicamente "conectado"). Por motivos como autenticação ou autorização incorreta ou uso de protocolo incorreto (como solicitação de um subprotocol, mas o próprio servidor não suporta o mesmo subprotocol), ou até mesmo uma tentativa de falar com um local de servidor que não seja um WebSocket como tentar se conectar aws://images.google.com/
)Fundamentalmente, se você
1006
vir um código fechado , terá um erro de nível muito baixo com o próprio WebSocket (semelhante a "Não foi possível abrir o arquivo" ou "Erro de soquete"), que não é realmente destinado ao usuário, pois aponta para um problema de baixo nível com seu código e implementação. Corrija seus problemas de baixo nível e, quando estiver conectado, poderá incluir códigos de erro mais razoáveis. Você pode fazer isso em termos de escopo ou gravidade em seu projeto. Exemplo: informações e nível de aviso fazem parte do protocolo específico do seu projeto e não fazem com que a conexão seja encerrada. Com relatórios de mensagens graves ou fatais, também usando o protocolo do seu projeto para transmitir quantos detalhes você deseja e, em seguida, fechando a conexão usando as capacidades limitadas do fluxo de fechamento do WebSocket.Esteja ciente de que os códigos de fechamento do WebSocket são definidos de forma muito estrita e a frase / mensagem do motivo do fechamento não pode exceder 123 caracteres de comprimento (esta é uma limitação intencional do WebSocket).
Mas nem tudo está perdido, se você está querendo essas informações apenas por motivos de depuração, os detalhes do fechamento e seu motivo subjacente são frequentemente relatados com uma quantidade razoável de detalhes no console Javascript do Chrome.
fonte
sok.onerror=function (evt) {console.log(evt);}
os detalhes não são tantos. Nem mesmo umreason
ou algo assim. Então, nenhuma opção? Acabei de mostrar ao usuário,something is wrong, or not connencted?
Não é tão amigável, seria bom se o usuário pudesse ver "Você não pode excluir, por causa das restrições do banco de dados". Alguma opção? Obrigadosok.onclose
vez disso, você deve usar os gatilhosclose event
que temreason
ecode
nelesok.onclose
funcionará para muitos caminhos, mas não todos os caminhos. Especialmente protocolo ruim, erros de handshake ruins (como algumas condições que podem causar fechamento de código1006
). Isso mudará no futuro? Provavelmente. Mas quando essa resposta foi escrita, era verdade.reason
retornado quando ele usouonerror
Eu estava apontando que este propriedadescode
ereason
específica paraclose
evento nãoerror
evento. então seria melhor para ele usaronclose
, estou faltando alguma coisa?1006
que tem um significado especial e tratamento especial na especificação do websocket e na API javascript do websocket. O motivo da string / mensagem em algumas1006
condições não é exposta de maneira específica e intencional em nenhum lugar da API. (como a resposta apontou). Este não é um bug na API, ele apenas aborda as várias especificações e suas preocupações sobre o abuso de websocket para fins não-websocket.No meu e possivelmente no caso do @BIOHAZARD foi
nginx proxy timeout
. Por padrão é60
seg sem atividade no soqueteMudei para 24h
nginx
e resolveu o problemafonte
Parece que este é o caso quando o Chrome não é compatível com o padrão WebSocket. Quando o servidor inicia o fechamento e envia o quadro fechado para um cliente, o Chrome considera isso um erro e relata para o lado JS com o código 1006 e nenhuma mensagem de motivo. Em meus testes, o Chrome nunca responde a frames de fechamento iniciados pelo servidor (código de fechamento 1000), sugerindo que o código 1006 provavelmente significa que o Chrome está relatando seu próprio erro interno.
PS Firefox v57.00 lida com este caso adequadamente e entrega com sucesso a mensagem de razão do servidor para o lado do JS.
fonte
Achei que isso poderia ser útil para outros. Saber regex é útil, crianças. Fique na escola.
Edit: Transformou-o em uma função dândi útil!
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' }
Fonte (com pequenas edições para concisão): https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
fonte
Recebi o erro ao usar o Chrome como cliente e golang gorilla websocket como servidor no proxy nginx
E enviar apenas uma mensagem "ping" do servidor para o cliente a cada x segundo resolveu o problema
fonte
Pode ser que o URL do seu websocket que você está usando no dispositivo não seja o mesmo (você está acessando um URL do websocket diferente de android / iphonedevice)
fonte