WebSocketがクローズコード1006でクローズされた理由を取得する


93

ユーザーに適切なメッセージを表示できるように、WebSocketを閉じる理由を取得したいと思います。

私は持っています

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

コードは常に1006であり、理由は常に「」です。しかし、私はさまざまな終了理由を区別したいと思います。

たとえば、コマンド行にはエラー理由が表示されます。「データベースでは削除できないため、削除できません」。しかし、Chromeのコンソールでは、理由はまだ「」です。

異なる終了理由を区別する他の方法はありますか?


これは、サーバーが接続/切断されたイベントを処理しているためだと思います。はっきりとは言えませんが、サーバー上でもコードを使用して接続の切断を正しく処理する必要があります。サーバーに組み込まれているOnConnected / Disconnectedメソッドをオーバーライドしてみてください。を参照してください。私の仮定は、あなたがそれを閉じているが、サーバーが適切に閉じていないため、適切な閉じた応答を中継していないということだけです。
Michael Puckett II

回答:


125

Close Code1006は、ブラウザの実装によって接続が異常に(ローカルに)閉じられたことを意味する特別なコードです。

ブラウザクライアントがクローズコードを報告する場合1006は、websocket.onerror(evt)イベントで詳細を確認する必要があります。

ただし、Chromeがコードのクローズ1006理由をJavascript側に報告することはめったにありません。これは、WebSocketの悪用を防ぐためのWebSocket仕様のクライアントセキュリティルールが原因である可能性があります。(宛先サーバーで開いているポートをスキャンしたり、サービス拒否攻撃のために大量の接続を生成したりするために使用するなど)。

1006WebsocketへのHTTPアップグレード中にエラーが発生した場合、Chromeはクローズコードを報告することが多いことに注意してください(これは、WebSocketが技術的に「接続」される前のステップです)。不正な認証または承認、不正なプロトコルの使用(サブプロトコルを要求するが、サーバー自体は同じサブプロトコルをサポートしていないなど)、またはWebSocketではないサーバーの場所と通信しようとするなどの理由(に接続しようとするなどws://images.google.com/

基本的に、近いコードが表示された場合1006、WebSocket自体に非常に低レベルのエラーがあり(「ファイルを開くことができません」または「ソケットエラー」に似ています)、低レベルの問題を示しているため、実際にはユーザー向けではありません。あなたのコードと実装で。低レベルの問題を修正し、接続時に、より妥当なエラーコードを含めることができます。これは、プロジェクトの範囲または重大度の観点から実現できます。例:情報と警告レベルはプロジェクト固有のプロトコルの一部であり、接続を終了させません。重大または致命的なメッセージレポートでは、プロジェクトのプロトコルを使用して必要な詳細を伝達し、WebSocketクローズフローの制限された機能を使用して接続を閉じます。

WebSocketのクローズコードは非常に厳密に定義されており、クローズ理由のフレーズ/メッセージの長さは123文字を超えることはできないことに注意してください(これは意図的なWebSocketの制限です)。

ただし、デバッグ上の理由でこの情報が必要な場合は、すべてが失われるわけではありません。クロージャーの詳細とその根本的な理由は、ChromeのJavascriptコンソールにかなりの詳細で報告されることがよくあります。


4
Joakim、ありがとう、非常に詳細な回答。私が使用sok.onerror=function (evt) {console.log(evt);}する場合、詳細はそれほど多くありません。でもreason何かでもありません。それで、オプションはまったくありませんか?ユーザーに表示するだけですが、something is wrong, or not connencted?あまりユーザーフレンドリーではありません。ユーザーに「データベースの制限のため、削除できません」と表示されていると便利です。オプションはありますか?ありがとう
slevin 2013年

sok.onclose代わりに、トリガーを使用する必要があります。トリガーclose eventreasonありcode、その中に
Ihab Khattab 2014年

@IhabKhattabは、クローズコード固有であり、クローズが発生したときも同様です。持つsok.oncloseことは多くのパスで機​​能しますが、すべてのパスで機​​能するわけではありません。特に悪いプロトコル、悪いハンドシェイクエラー(コードを閉じる原因となる可能性のあるいくつかの条件など1006)。これは将来変更されますか?多分。しかし、この答えが書かれたとき、それは真実でした。
Joakim Erdfelt 2014年

彼は何もしているについては申し訳ありません@JoakimErdfelt、私は@slevin質問に返答しなかったreason彼が使用したときに返されたonerror私は、このプロパティをその指していたcodereasonする特定のcloseイベントではないerrorイベント。だからonclose代わりに使うほうがいいでしょう、私は何かが足りないのですか?
Ihab Khattab 2014年

@IhabKhattabはい、彼の質問は1006特別な意味を持つエラーコード、WebSocket仕様、およびjavascript websocketapiでの特別な処理について具体的だったためです。一部の1006条件下での理由文字列/メッセージは、APIのどこにも具体的かつ意図的に公開されていません。(答えが指摘したように)。これはAPIのバグではなく、WebSocket以外の目的でWebSocketを悪用することに関するさまざまな仕様とその懸念に対処するだけです。
Joakim Erdfelt 2014年

19

私の、そしておそらく@BIOHAZARDの場合、それはでしたnginx proxy timeout。デフォルトで60は、ソケットでのアクティビティなしの秒です

24時間制に変更したところ、nginx問題は解決しました

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;

これをありがとう!私の場合、これが1006エラーの理由です。
スティーブハノフ

11

これは、ChromeがWebSocket標準に準拠していない場合のようです。場合は、サーバーを開始近いし、クライアントに近いフレームを送信し、Chromeは、これは誤りであると考え、コード1006と理由メッセージを持たないJS側にそれを報告します。私のテストでは、Chromeはサーバーが開始したクローズフレーム(クローズコード1000)に応答しません。これは、コード1006がChromeが独自の内部エラーを報告していることを意味している可能性があることを示しています。

PS Firefox v57.00はこのケースを適切に処理し、サーバーの理由メッセージをJS側に正常に配信します。


4

これは他の人にとって便利かもしれないと思った。子供たち、正規表現を知ることは役に立ちます。学校にいなさい。

編集:それを便利なダンディ機能に変えました!

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


npmパッケージはどうですか?:-)
ピラニア

@Pirannaどうぞ。;)
Andrew

1

nginxプロキシでChromeをクライアントとして使用し、golang gorillawebsocketをサーバーとして使用しているときにエラーが発生しました

そして、x秒ごとにサーバーからクライアントに「ping」メッセージを送信するだけで問題が解決しました


0

これは、デバイスで使用しているWebSocket URLが同じではない可能性があります(android / iphonedeviceとは異なるWebSocket URLをヒットしています)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.