Je voudrais obtenir la raison de la fermeture des websockets, afin que je puisse montrer le bon message à l'utilisateur.
j'ai
sok.onerror=function (evt)
{//since there is an error, sockets will close so...
sok.onclose=function(e){
console.log("WebSocket Error: " , e);}
Le code est toujours 1006 et la raison est toujours "". Mais je veux distinguer différentes raisons de clôture.
Par exemple, la ligne de commande donne une raison d'erreur: "vous ne pouvez pas supprimer cela, car la base de données ne vous le permettra pas". Mais sur la console de Chrome, la raison est toujours "".
Une autre façon de distinguer les différentes raisons de clôture?
javascript
websocket
slevin
la source
la source
Réponses:
Fermer le code
1006
est un code spécial qui signifie que la connexion a été fermée anormalement (localement) par l'implémentation du navigateur.Si votre navigateur client signale un code de fermeture
1006
, alors vous devriez regarder l'websocket.onerror(evt)
événement pour plus de détails.Cependant, Chrome signalera rarement les
1006
raisons du code de fermeture du côté Javascript. Cela est probablement dû aux règles de sécurité du client dans la spécification WebSocket pour empêcher toute utilisation abusive de WebSocket. (comme son utilisation pour rechercher des ports ouverts sur un serveur de destination ou pour générer de nombreuses connexions pour une attaque par déni de service).Notez que Chrome signalera souvent un code de fermeture en
1006
cas d'erreur lors de la mise à niveau HTTP vers Websocket (il s'agit de l'étape avant qu'un WebSocket ne soit techniquement «connecté»). Pour des raisons telles qu'une mauvaise authentification ou autorisation, ou une mauvaise utilisation du protocole (comme la demande d'un sous-protocole, mais le serveur lui-même ne prend pas en charge ce même sous-protocole), ou même une tentative de communication avec un emplacement de serveur qui n'est pas un WebSocket ( comme tenter de se connecter àws://images.google.com/
)Fondamentalement, si vous voyez un code de fermeture
1006
, vous avez une erreur de très bas niveau avec WebSocket lui-même (similaire à "Impossible d'ouvrir le fichier" ou "Erreur de socket"), pas vraiment destinée à l'utilisateur, car elle indique un problème de bas niveau avec votre code et votre implémentation. Résolvez vos problèmes de bas niveau, puis lorsque vous êtes connecté, vous pouvez alors inclure des codes d'erreur plus raisonnables. Vous pouvez accomplir cela en termes de portée ou de gravité dans votre projet. Exemple: les informations et le niveau d'avertissement font partie du protocole spécifique de votre projet et ne provoquent pas l'arrêt de la connexion. Avec des messages graves ou fatals, les rapports utilisent également le protocole de votre projet pour transmettre autant de détails que vous le souhaitez, puis la fermeture de la connexion en utilisant les capacités limitées du flux de fermeture WebSocket.Sachez que les codes de fermeture de WebSocket sont très strictement définis et que la phrase / le message de raison de fermeture ne peut pas dépasser 123 caractères (il s'agit d'une limitation intentionnelle de WebSocket).
Mais tout n'est pas perdu, si vous ne voulez que ces informations pour des raisons de débogage, le détail de la fermeture et sa raison sous-jacente sont souvent signalés avec beaucoup de détails dans la console Javascript de Chrome.
la source
sok.onerror=function (evt) {console.log(evt);}
les détails ne sont pas tellement. Pas même unreason
ou quelque chose. Alors, pas d'options du tout? Je viens de montrer à l'utilisateur,something is wrong, or not connencted?
pas si convivial, ce serait bien si l'utilisateur peut voir "Vous ne pouvez pas supprimer, cause des restrictions de base de données". Des options? Mercisok.onclose
place quels déclencheursclose event
, il areason
etcode
dedanssok.onclose
fonctionnera pour de nombreux chemins, mais pas pour tous les chemins. Protocole particulièrement mauvais, mauvaises erreurs de prise de contact (comme certaines conditions qui pourraient provoquer un code de fermeture1006
). Cela changera-t-il à l'avenir? Probablement. Mais quand cette réponse a été écrite, c'était vrai.reason
retour quand il a utilisé,onerror
je signalais que ces propriétéscode
etreason
spécifiques à l'close
événement et non à l'error
événement. il vaudrait donc mieux qu'il l' utilise à laonclose
place, est-ce que je manque quelque chose?1006
qui a une signification particulière, et une gestion spéciale dans la spécification websocket et l'api javascript websocket. La chaîne / le message de raison dans certaines1006
conditions n'est spécifiquement et intentionnellement exposé nulle part dans l'API. (comme la réponse l'a souligné). Ce n'est pas un bogue dans l'API, il répond simplement aux diverses spécifications et à leurs préoccupations concernant l'utilisation abusive de websocket à des fins non-websocket.Dans mon cas et peut-être @BIOHAZARD, c'était le cas
nginx proxy timeout
. Par défaut, c'est60
sec sans activité dans le socketJe l'ai changé en 24h
nginx
et le problème a été résoluproxy_read_timeout 86400s; proxy_send_timeout 86400s;
la source
Il semble que ce soit le cas lorsque Chrome n'est pas conforme à la norme WebSocket. Lorsque le serveur lance la fermeture et envoie une trame de fermeture à un client, Chrome considère qu'il s'agit d'une erreur et la signale au côté JS avec le code 1006 et aucun message de raison. Dans mes tests, Chrome ne répond jamais aux cadres de fermeture déclenchés par le serveur (code de fermeture 1000), ce qui suggère que le code 1006 signifie probablement que Chrome signale sa propre erreur interne.
PS Firefox v57.00 gère ce cas correctement et envoie avec succès le message de raison du serveur au côté JS.
la source
J'ai pensé que cela pourrait être utile pour les autres. Connaître les regex est utile, les enfants. Rester à l'école.
Edit: Je l'ai transformé en une fonction dandy pratique!
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)'; }
Usage:
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' }
Source (avec des modifications mineures pour la concision): https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
la source
J'ai l'erreur en utilisant Chrome comme client et golang gorilla websocket comme serveur sous proxy nginx
Et envoyer juste un message "ping" du serveur au client toutes les x secondes problème résolu
la source
Il se peut que l'URL de votre websocket que vous utilisez dans l'appareil ne soit pas la même (vous rencontrez une URL de websocket différente à partir d'android / iphonedevice)
la source