A WebSocket Message Has Been Received

メッセージ受信 (WebSocket)

仕様書

処理

[6] WebSocket接続の確立によりWebSocket接続の状態が OPEN になると、以後の受信データは次のように処理されることになります。

[5] WebSocket の規定に従わないクライアントは、 WebSocket handshake におけるサーバーからの応答を待たずにフレーム (やフレームになっていないデータ) を送信するかもしれません。サーバーはそれに特別な対処を行う必要はありませんが、 >>60 を根拠に切断しても良いのかもしれません。

[53] 受信したデータは、次のように処理しなければなりません

  1. [37] WebSocket接続WebSocket接続失敗であれば、停止します >>36
  2. [9] WebSocketフレームとして構文解析します >>54
    1. [40] フレームの長さを決定します。WebSocketフレームの項を参照。ここで接続が閉じられることもあります。
  3. [60] 不正なデータなら、TCP接続を切断して構いません。 次のようにするべきです>>59
    1. [7] Closeフレームを送信します。
    2. [8] WebSocket接続を閉じる処理を実行します。
    3. [15] 停止します。
  4. [13] 自身がサーバーであり、フレームマスクされていないか、 自身がクライアントであり、フレームマスクされているなら、
    1. [19] Closeフレーム状態符号 1002 で送信して構いません >>10
    2. [18] 接続を閉じます >>10
  5. [41] FIN が 0 で opcode が 0x8, 0x9, 0xA なら、 WebSocket接続失敗を実行し、停止します。
  6. [14] 次の場合は、WebSocket接続失敗を実行し、停止します。 >>10
    • [16] RSV1 が非 0 値であり、拡張のいずれの規定にも拠っていない場合
    • [17] RSV2 が非 0 値であり、拡張のいずれの規定にも拠っていない場合
    • [11] RSV3 が非 0 値であり、拡張のいずれの規定にも拠っていない場合
  7. [12] 未知の opcode の場合は、WebSocket接続失敗を実行し、停止します。 >>10
  8. [58] 自身がサーバーなら、マスクを除去します >>54
  9. [55] 制御フレームなら、その規定により処理します >>54。 (Closeフレーム, Pingフレーム, Pongフレームを参照。)
  10. [22] 継続フレームなら、
    1. [23] 不完全なメッセージが無いなら、 WebSocket接続失敗を実行し停止するべきと思われます。
    2. [24] 不完全なメッセージpayloadデータフレームpayloadデータを連結します。 拡張により規定がある場合は、その方法によります >>54
  11. [25] テキストフレームバイナリーフレームなら、
    1. [26] 不完全なメッセージがあるなら、 WebSocket接続失敗を実行し停止するべきと思われます。
    2. [27] 不完全なメッセージを、本フレームに設定します。
  12. [28] フレームFIN1 なら、
    1. [29] 不完全なメッセージpayloadデータ拡張の規定 (あれば) により処理します >>54
    2. [30] 不完全なメッセージテキストフレームなら、
      1. [31] 応用データUTF-8 として復号します。
      2. [32] 復号に失敗したら、WebSocket接続失敗を実行し、停止します >>21
    3. [56] WebSocketメッセージを受信 (A WebSocket Message Has Been Received) を実行します。テキストフレームなら復号した文字列を、バイナリーフレームなら応用データを引き渡します。 >>54
    4. [33] 不完全なメッセージを、 null に設定します。

[20] RFC はエラー処理を曖昧にしか規定していません。 (IETF ではよくあることです。)
[35] RFC は閉じ方が規定毎に違う説明になっていますが、何か意図的なのか、 すべてWebSocket接続失敗と同じとみなして良いのか不明です。

[38] Chromeマスクフラグ → RSV フラグ → opcode の順に検査するようです。

[39] Chromeマスクされている場合、予約ビットが立っている場合、未知 opcode が使われている場合に、状態符号1002Closeフレームを送信します。 理由はそれぞれ Masked frame from server, Invalid reserved bit, Unknown opcode です。 Firefox はこれらの場合に何も送信せずに接続を閉じるようです。

[52] 扱えるフレームのサイズや断片化を結合したメッセージのサイズに上限がある実装は、 それを超えないよう自身を保護しなければなりません >>50

[2] 利用者エージェントは、種別種別のデータメッセージデータWebSocketメッセージを受信したら、 WebSocket オブジェクトオブジェクトについて、 次のタスクタスクキューに追加しなければなりません >>1

[43] タスク
タスク源
WebSocketタスク源
処理
  1. [46] オブジェクトreadyStateOPEN (1) でなければ、停止します。
  2. [48] 種別により、
    テキスト
    データを、メッセージデータに設定します。
    バイナリー
    オブジェクトbinaryType により、
    blob
    データを、オブジェクト関連Realmにおける、 生データメッセージデータである新しい Blob に設定します。
    arraybuffer
    データを、オブジェクト関連Realmにおける、 内容メッセージデータである新しい ArrayBuffer に設定します。
  3. [44] イベント発火します。
    [45] イベント
    インターフェイス
    MessageEvent
    イベント型
    message
    対象
    オブジェクト
    trusted
    bubbles
    取り消し可能
    origin
    オブジェクトurl起源直列化
    data
    data

[3] 利用者エージェントは、本タスクの実行の時に効率的に実行する条件が満たされていなければ、実行を遅延させて他のタスクキュータスクを実行することが推奨 (encouraged) されています。 >>1

[4] 例えば、受信したデータがディスクにあり、タスク実行時点で binaryTypearraybuffer になっていれば、 データをメモリーに読み込む処理を実行し、その完了まで他のタスクを実行していることができます。 >>1

[34] サーバーは、WebSocketメッセージを受信したら、適宜必要な処理を実行できます。

歴史

[42] Editorial: more minor event creation/dispatch cleanup (domenic著, ) <https://github.com/whatwg/html/commit/5fafa73c8ad57f2d98e9c978200e11199fb26bdc>

[47] Specify the realm used for WebSocket-created Blobs and ArrayBuffers (domenic著, ) <https://github.com/whatwg/html/commit/6bf5e4414af4bc2d5fd723443b21f5ada45532fb>

[49] Remove Unicode serialization of an origin (annevk著, ) <https://github.com/whatwg/html/commit/59ebd9c094d9d532458a9ee61f307bf41bc70811>