Erhalten des Grundes, warum Websockets mit dem Schließcode 1006 geschlossen wurden

91

Ich möchte den Grund für das Schließen von Websockets erhalten, damit ich dem Benutzer die richtige Nachricht anzeigen kann.

ich habe

sok.onerror=function (evt) 
     {//since there is an error, sockets will close so...
       sok.onclose=function(e){
           console.log("WebSocket Error: " , e);}

Der Code ist immer 1006 und der Grund ist immer "". Aber ich möchte verschiedene abschließende Gründe auseinanderhalten.

Zum Beispiel gibt die Befehlszeile einen Fehlergrund an: "Sie können das nicht löschen, weil die Datenbank dies nicht zulässt". Aber auf der Chrome-Konsole ist der Grund immer noch "".

Gibt es eine andere Möglichkeit, verschiedene Abschlussgründe voneinander zu unterscheiden?

Slevin
quelle
Ich denke, das liegt daran, wie der Server die verbundenen / getrennten Ereignisse behandelt. Ich kann nicht sicher sagen, aber das Schließen der Verbindung muss auf dem Server auch mit Code korrekt gehandhabt werden. Versuchen Sie, die auf dem Server integrierten On Connected / Disconnected-Methoden zu überschreiben, und lesen Sie. Ich gehe nur davon aus, dass Sie es schließen, aber der Server nicht richtig schließt und daher nicht die richtige geschlossene Antwort weiterleitet.
Michael Puckett II

Antworten:

122

Close Code1006 ist ein spezieller Code, der bedeutet, dass die Verbindung von der Browser-Implementierung abnormal (lokal) geschlossen wurde.

Wenn Ihr Browser-Client Abschlusscode meldet 1006, sollten Sie sich das websocket.onerror(evt)Ereignis nach Details ansehen.

Chrome meldet 1006der Javascript-Seite jedoch selten Gründe für einen engen Code . Dies ist wahrscheinlich auf Client-Sicherheitsregeln in der WebSocket-Spezifikation zurückzuführen, um den Missbrauch von WebSocket zu verhindern. (z. B. zum Scannen nach offenen Ports auf einem Zielserver oder zum Generieren vieler Verbindungen für einen Denial-of-Service-Angriff).

Beachten Sie, dass Chrome häufig einen Abschlusscode meldet, 1006wenn während des HTTP-Upgrades auf Websocket ein Fehler auftritt (dies ist der Schritt, bevor ein WebSocket technisch "verbunden" wird). Aus Gründen wie einer schlechten Authentifizierung oder Autorisierung oder einer schlechten Protokollverwendung (z. B. dem Anfordern eines Unterprotokolls, aber der Server selbst unterstützt dasselbe Unterprotokoll nicht) oder sogar dem Versuch, mit einem Serverstandort zu sprechen, der kein WebSocket ist ( wie der Versuch, eine Verbindung zu herzustellen ws://images.google.com/)

Wenn Sie einen geschlossenen Code sehen 1006, haben Sie grundsätzlich einen Fehler auf sehr niedriger Ebene mit WebSocket selbst (ähnlich wie "Datei kann nicht geöffnet werden" oder "Socket-Fehler"), der nicht wirklich für den Benutzer gedacht ist, da er auf ein Problem auf niedriger Ebene hinweist mit Ihrem Code und Ihrer Implementierung. Beheben Sie Ihre Probleme auf niedriger Ebene, und wenn Sie verbunden sind, können Sie vernünftigere Fehlercodes einfügen. Sie können dies in Bezug auf Umfang oder Schweregrad in Ihrem Projekt erreichen. Beispiel: Info- und Warnstufe sind Teil des spezifischen Protokolls Ihres Projekts und führen nicht dazu, dass die Verbindung beendet wird. Bei schwerwiegenden oder schwerwiegenden Meldungen wird auch das Protokoll Ihres Projekts verwendet, um so viele Details wie gewünscht zu übermitteln, und anschließend wird die Verbindung mithilfe der eingeschränkten Funktionen des WebSocket Close Flow geschlossen.

Beachten Sie, dass WebSocket-Schließcodes sehr streng definiert sind und die Abschlussgrundphrase / -nachricht nicht länger als 123 Zeichen sein darf (dies ist eine absichtliche WebSocket-Einschränkung).

Es ist jedoch nicht alles verloren, wenn Sie diese Informationen nur aus Debugging-Gründen benötigen. Die Details des Abschlusses und die zugrunde liegenden Gründe werden in der Javascript-Konsole von Chrome häufig mit ziemlich vielen Details angegeben.

Joakim Erdfelt
quelle
4
Joakim, danke, sehr ausführlicher anser. Wenn ich sok.onerror=function (evt) {console.log(evt);}die Details benutze, sind sie nicht so sehr. Nicht einmal ein reasonoder so. Also überhaupt keine Optionen? Ich zeige nur dem Benutzer, something is wrong, or not connencted?nicht so benutzerfreundlich, es wäre schön, wenn der Benutzer sehen könnte "Sie können nicht löschen, wegen Datenbankbeschränkungen". Irgendwelche Optionen? Danke
Slevin
Sie sollten sok.onclosestattdessen verwenden, welche Auslöser close eventes hat reasonund codedarin
Ihab Khattab
@IhabKhattab, das eng Code-spezifisch wäre, und auch, wenn das Schließen auftritt. Haben sok.onclosewird für viele Pfade funktionieren, aber nicht für alle Pfade. Besonders schlechtes Protokoll, schlechte Handshake-Fehler (wie einige Bedingungen, die zu einem engen Code führen können 1006). Wird sich dies in Zukunft ändern? Wahrscheinlich. Aber als diese Antwort geschrieben wurde, war es wahr.
Joakim Erdfelt
@JoakimErdfelt Entschuldigung, ich habe auf die Frage von @slevin geantwortet, dass er reasonbei seiner Verwendung nicht zurückgekehrt ist. onerrorIch habe darauf hingewiesen, dass diese Eigenschaften code& reasonspezifisch für closeEreignis nicht errorEreignis sind. Also wäre es besser für ihn , onclosestattdessen etwas zu verwenden. Vermisse ich etwas?
Ihab Khattab
@IhabKhattab ja, da seine Frage spezifisch war für Fehlercode, 1006der eine besondere Bedeutung hat, und eine spezielle Behandlung in der Websocket-Spezifikation und der Javascript-Websocket-API. Der Grund, warum Zeichenfolge / Nachricht unter bestimmten 1006Bedingungen spezifisch und absichtlich nirgendwo in der API verfügbar gemacht wird. (wie die Antwort zeigte). Dies ist kein Fehler in der API, sondern lediglich die verschiedenen Spezifikationen und ihre Bedenken hinsichtlich des Missbrauchs von Websockets für Nicht-Websocket-Zwecke.
Joakim Erdfelt
13

In meinem und möglicherweise @BIOHAZARD Fall war es nginx proxy timeout. Standardmäßig ist es 60sec ohne Aktivität im Socket

Ich habe es auf 24 Stunden geändert nginxund das Problem wurde behoben

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
MixerOID
quelle
Danke dafür! Dies ist in meinem Fall der Grund für den 1006-Fehler.
Steve Hanov
10

Dies scheint der Fall zu sein, wenn Chrome nicht dem WebSocket-Standard entspricht. Wenn der Server das Schließen initiiert und das Schließen eines Frames an einen Client sendet, betrachtet Chrome dies als Fehler und meldet ihn mit dem Code 1006 und ohne Grundmeldung an die JS-Seite. In meinen Tests reagiert Chrome niemals auf vom Server initiierte Close Frames (Close Code 1000), was darauf hindeutet, dass Code 1006 wahrscheinlich bedeutet, dass Chrome seinen eigenen internen Fehler meldet.

PS Firefox v57.00 behandelt diesen Fall ordnungsgemäß und übermittelt die Ursachenmeldung des Servers erfolgreich an die JS-Seite.

user10663464
quelle
2

Dachte, dies könnte für andere nützlich sein. Regex zu kennen ist nützlich, Kinder. In der Schule bleiben.

Bearbeiten: Verwandelte es in eine praktische Dandy-Funktion!

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)';
}

Verwendung:

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'
}

Quelle (mit geringfügigen Änderungen für die Knappheit): https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes

Andrew
quelle
1

Ich habe den Fehler bei der Verwendung von Chrome als Client und Golang Gorilla Websocket als Server unter Nginx Proxy

Und jede x Sekunde wird nur eine "Ping" -Nachricht vom Server an den Client gesendet. Das Problem wurde behoben

BIOHAZARD
quelle
0

Dies kann sein, dass Ihre Websocket-URL, die Sie im Gerät verwenden, nicht identisch ist (Sie treffen eine andere Websocket-URL von Android / Iphonedevice).

Ankush Sahu
quelle