W3C - 『The WebSocket API』日本語訳

一部、直訳ではなく意訳した部分がございます。原文と表現が異なることがございますので、ご了承ください。この日本語訳は、私が理解を深めるために、自分なりに日本語化したものです。本日本語訳には、翻訳上の誤りがある可能性があります。したがって、内容について一切保証をするものではありません。正確さを求める場合には、必ず原文を参照してください。当方は、この文書によって利用者が被るいかなる損害の責任を負いません。もし誤りなどを見つけたら、当サイトのお問い合わせより連絡いただければ幸いです。

概要

WebSocket は、JavaScript からサーバーとの双方向通信を行いメッセージ交換を実現する API です。XHR では実現できなかったようなリアルタイムの対話が実現できますので、これまでには無かった新しいウェブアプリケーションを予感できます。

現在は W3C の HTML5 仕様から分離されてしまいましたが、次世代のウェブアプリケーションの中核を担うテクノロジーとして期待されています。


要約

この仕様では、ウェブページがリモートホストとの双方向通信のために WebSocket プロトコルを使えるようにする API を定義しています。

本文書の状態

このセクションでは、発行時における本文書の状態を説明します。本文書は他の文書によって置き換えられるかもしれません。現在の W3C の発行物と、この技術に関するレポートの最新の公式の公開リビジョンの一覧は、http://www.w3.org/TR/ の W3C technical reports index をご覧ください。

W3C に見てもらえるよう本文書に関してコメントをご希望の場合は、公開バグ・データベースを使って投稿してください。アカウントをお持ちでない場合は、このフォームを使ってフィードバックを入れることができます:

フィードバック・コメント

あなたのフィードバックを入れてください。あなたがフィードバックを投稿しようとしているセクションのタイトルを忘れないように入れてください。必要ならば、今時点で誤っているテキストを引用してください。もし新たな機能を提案しようとしているなら、あなたが解決しようとしている問題が何なのかを言うことは、非常に重要なことです。それは、実際には、解決策よりも重要なのです。

セクション番号を使わないでください。それは、すぐに変わってしまうかもしれず、あなたのフィードバックが分かりにくくなってしまうからです。

(あなたの IP アドレスとユーザー・エージェントは、スパム防止の理由により公に記録されますのでご了承ください。)

コメントがあれば、public-webapps@w3.org (subscribe, archives), or whatwg@whatwg.org (subscribe, archives) に送ってください。どんなフィードバックでも歓迎です。

この議論に参加していない実装者は、この仕様を逸脱して、互換性がなくなってしまうような解釈をしてしまうかもしれません。勧告候補の段階に達する前に、この仕様の実装に興味を持ったベンダーは、前述のメーリングリストに加わって、議論に参加するべきです。

本仕様の編集者草案の最新の安定バージョンは、W3C の CVS サーバWHATWG の Subversion リポジトリからいつでも入手可能です。最新の編集者作業版(準備中のため未完成のテキストも含まれるかもしれません) には、本仕様の最新の草案テキストが含まれています(その他も含む)。詳細は WHATWG FAQ をご覧ください。

本仕様の変更の通知は、次のメカニズムを使って、関連の仕様の変更の通知とともに送られます:

E-mail による変更通知
Commit-Watchers mailing list (complete source diffs): http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org
全変更点のバージョン管理記録:
CVSWeb interface with side-by-side diffs: http://dev.w3.org/cvsweb/html5/
Annotated summary with unified diffs: http://html5.org/tools/web-apps-tracker
Raw Subversion interface: svn checkout http://svn.whatwg.org/webapps/

W3C の Web Apps ワーキンググループは、W3C 勧告トラックに沿ってこの仕様の進捗に責任を持つ W3C ワーキンググループです。この仕様は、2011年 9 月 29 日版の最終草案です。最終草案レビューは、2011 年 10 月 21 日までです。

この仕様は、有線プロトコルである WebSocket プロトコルの Internet Draft と連動して開発されています。

本文書は、5 February 2004 W3C Patent Policy に基づき運営するグループによって作られました。W3C は、グループの成果物に関連して作られた public list of any patent disclosures をメンテナンスしています。そのページには、特許を開示する方法も掲載されています。Essential Claim(s) を含むと信じる特許の実知識を持つ個人は、section 6 of the W3C Patent Policy に従って情報を開示しなければいけません。

目次

  1. 1 はじめに
  2. 2 準拠要件
    1. 2.1 依存関係
  3. 3 用語の定義
  4. 4 WebSocket インタフェース
  5. 5 プロトコルからのフィードバック
    1. 5.1 イベント定義
    2. 5.2 ガーベッジ・コレクション
  6. リファレンス
  7. 謝辞

1 はじめに

このセクションは非規定です。

ウェブ・アプリケーションからサーバー側プロセスと双方向通信ができるようにするために、本仕様では WebSocket インタフェースを導入します。

このインタフェースから下層ネットワークに対して直接アクセスすることはできません。例えば、このインタフェースを使って IRC クライアントを実装することはできないでしょう。そうするためには、メッセージを独自サーバーに介してプロクシしなければいけません。T

2 準拠要件

この仕様では、それぞれの節で非規定と記載されていれば、その節にある図表や例や注意事項はすべて非規定です。それ以外はすべて規定です。

この仕様の規定部分にある "しなければいけない(MUST)", "してはいけない(MUST NOT)", "する必要がある・必須である(REQUIRED)", "するべきである(SHOULD)", "すべきではない(SHOULD NOT)", "推奨される(RECOMMENDED)", "しても構わない・することができる(MAY)", "オプションで(OPTIONAL)" というキーワードは、RFC2119の規定通りに解釈してください。 この仕様では、読みやすくするために、これらの言葉すべてを大文字で表現しています。 [RFC2119]

アルゴリズムの一部として規範の中で述べられる要件("strip any leading space characters" や "return false and abort these steps" など)は、そのアルゴリズムの紹介で使われるキーワード("must", "should", "may", など)の意味で解釈するべきです。

いくつかの準拠要件は、属性、メソッド、オブジェクトにおける要件として述べられています。このような要件は、ユーザーエージェントにおける要件として解釈するべきです。

アルゴリズムや特定の手順として述べられている準拠要件は、最終的な結果が同じ限り、どのような方法で実装しても構いません。(特に、この仕様で定義されるアルゴリズムは読みやすさを考慮したものであり、パフォーマンスを考慮しているわけではありません。)

この仕様で定義される準拠クラスは、ユーザーエージェントだけです。

ユーザーエージェントは、他の入力に関する実装上の制限を自発的に課しても構いません。例えば、DoS 攻撃を防止するためや、メモリ不足を防ぐためや、プラットフォーム固有の制限に対する回避策などです。

機能のサポートを無効にするとき(セキュリティ問題を低減するための緊急的な手段として、または、開発を補助するため、または、パフォーマンスの理由のた め) は、ユーザーエージェントはその機能をまったくサポートしていないかのように、そして、その機能が本仕様には無かったかのように振る舞わなければいけませ ん。たとえば、特定の機能が Web IDL インタフェースにある属性を通してアクセスできるなら、その属性そのものは、そのインタフェースを持ったオブジェクトから除外されます。その属性をオブ ジェクトに残しておきつつ、null を返したり、例外を投げるようにしただけでは十分ではありません。

2.1 依存関係

この仕様は、いくつかの下層の仕様に依存しています。

HTML

HTML の多くの基本的な概念が本仕様で使われています。[HTML]

WebIDL

本仕様の IDL ブロックには WebIDL 仕様のセマンティクスを使っています。[WEBIDL]

3 用語の定義

"Foo オブジェクト" といったら、 Foo は実質的にインタフェースを指すわけですが、"Foo インタフェースを実装したオブジェクト" というより正確な言い方が代わりに使われることがあります。

DOM という用語は、ウェブ・アプリケーションでスクリプトから利用できるようにした API 群を指すために使われますが、必ずしも、DOM Core 仕様で定義されているような Document オブジェクトや他の Node オブジェクトが実際に存在することを意味しているわけではありません。 [DOMCORE]

IDL 属性は、その値が(例えば、ウェブ制作者側のスクリプトによって)取り出されているときには、"取得される" と言い、それに新しい値が割り当てられるときには、"セットされる"と言います。

4 WebSocket インタフェース

[Constructor(DOMString url, optional DOMString protocols),
 Constructor(DOMString url, optional DOMString[] protocols)]
interface WebSocket : EventTarget {
  readonly attribute DOMString url;

  // ready state
  const unsigned short CONNECTING = 0;
  const unsigned short OPEN = 1;
  const unsigned short CLOSING = 2;
  const unsigned short CLOSED = 3;
  readonly attribute unsigned short readyState;
  readonly attribute unsigned long bufferedAmount;

  // networking
           attribute Function? onopen;
           attribute Function? onerror;
           attribute Function? onclose;
  readonly attribute DOMString extensions;
  readonly attribute DOMString protocol;
  void close([Clamp] optional unsigned short code, optional DOMString reason);

  // messaging
           attribute Function? onmessage;
           attribute DOMString binaryType;
  void send(DOMString data);
  void send(ArrayBuffer data);
  void send(Blob data);
};

WebSocket(url, protocols) コンストラクタは、一つか二つの引数を取ります。第一引数 url には、どこに接続するのかを URL で指定します。第二引数 protocols を指定するなら、文字列、もしくは、文字列の配列のいずれかを指定します。もし文字列が指定されたら、その文字列だけを含んだ配列と同等です。省略されたら、空の配列と同等です。配列のそれぞれの文字列はサブプロトコル名です。サーバーがこれらのサブプロトコルの一つを選択したと報告するなら、そのコネクションだけが確立されます。サブプロトコルの名前はいずれも、WebSocket プロトコル仕様で定義された Sec-WebSocket-Protocol ヘッダー・フィールドの値から構成される要素要件に一致する文字列でなければいけません。 [WSP]

WebSocket() コンストラクタが呼び出されたら、ユーザーエージェントは次の手順を実行しなければいけません:

  1. url 引数からの WebSocket の URL コンポーネントをパースして、host, port, resource name, secure を取得します。これが失敗したら、SYNTAX_ERR 例外を投げ、これらの手順を中止します。[WSP]

  2. secure が false にもかかわらず、エントリー・スクリプトのオリジンが、HTTPS など、それ自身、セキュア・プロトコルである scheme コンポーネントを持つなら、SECURITY_ERR 例外を投げます。

  3. port がユーザーエージェントによってアクセスをブロックするよう設定されているポートなら、SECURITY_ERR 例外を投げます。(通常、ユーザーエージェントは SMTP のような well-known ポートへのアクセスをブロックします)

    ポート 80 や 443 へのアクセスは、secure が false にもかかわらず port が 443、または、 secure が true にもかかわらず port が 80 といったあり得ない場合も含めて、ブロックされるべきではありません。

  4. protocols が存在しないなら、protocols を空の配列とします。

    そうでなければ、protocols が存在し、それが文字列なら、protocols をその文字列だけから構成される配列に置き換えます。

  5. protocols に同じ値が含まれていたり、WebSocket プロトコル仕様で定義された Sec-WebSocket-Protocol ヘッダー・フィールドの値から構成される要素要件に一致しない値があれば、SYNTAX_ERR 例外を投げ、これらの手順を中止します。 [WSP]

  6. origin を、エントリー・スクリプトのオリジンの ASCII シリアライゼーションとします。ただし、小文字に変換されたものとします。

  7. 新しい WebSocket オブジェクトを返し、バックグラウンドで、これらの手順を継続します(スクリプトをブロッキングしません)。

  8. 指定された host, port, resource name, secure を使って、protocols リスト、拡張に空リスト、そして origin とともに、 WebSocket コネクションを確立します。妥当な cookie を送信するヘッダーは、ユーザーの cookie ストアと URL url から計算された cookie 文字列を値とした Cookie ヘッダーでなければいけません。これらの目的においては、これは "非 HTTP" API ではありません。 [WSP] [COOKIES]

    ユーザーエージェントが "WebSocket コネクション確立" アルゴリズムにおいて、サーバーの応答の妥当性を検証するとき、サーバーから受信したステータス・コードが 101 (リダイレクトなど)でなければ、ユーザーエージェントは websocket コネクションを失敗としなければいけません

    この HTTP 手順に従うと、ウェブ・ブラウザー・コンテキストに深刻なセキュリティー問題が引き起こされる可能性があります。例えば、ひとつのパスに WebSocket サーバー、そして、別のパスに公開 HTTP リダイレクターを持つサーバーを考えてみてください。不意に特定の WebSocket URL を指定できてしまうスクリプトだったら、インターネット上のどのサーバーにも通信することができてしまいます。たとえ、そのスクリプトで URL に適切なホスト名が含まれているかをチェックしたとしてもです。

    WebSocket コネクション確立アルゴリズムが失敗したら、WebSocket コネクション失敗アルゴリズムが呼び出されます。これによって、WebSocket コネクション切断アルゴリズムが呼び出されます。これによって、WebSocket コネクション切断が確立され、後述の通りclose イベントが発出されます。

このコンストラクタは、スクリプトのグローバル・オブジェクトが Window オブジェクトか WorkerUtils インタフェースを実装したオブジェクトのいずれかであるときに、見えるようにしなければいけません。


url 属性は、コンストラクタに引数として渡された URL を解決した結果を返さなければいけません。 (それが、どこを相対基準として解決されたのかについては問題ではありません。なぜなら、それはすでに絶対 URL だと分かっているからです。)

readyState 属性は、コネクションの状態を表します。これは次の値を取ります:

CONNECTING (数値 0)
コネクションがまだ確立されていない。
OPEN (数値 1)
WebSocket コネクションが確立され、通信が可能。
CLOSING (数値 2)
コネクションは切断ハンドシェイク中。
CLOSED (数値 3)
コネクションが切断された、または、開くことができなかった。

オブジェクト生成時、その readyState には CONNECTING (0) がセットされなければいけません。

extensions 属性は当初は空文字列を返さなければいけません。後述の通り、WebSocket コネクションが確立されたら、この値が変わります。

extensions 属性は、サーバーによって選択された拡張があれば、それを返します。(現在のところ、これは空文字列しか返さないことになります。)

protocol 属性は、最初は空文字列を返さなければいけません。後述の通り、WebSocket コネクションが確立されたら、その値が変わります。

protocol 属性は、サーバーによって選択されたサブプロトコルがあれば、それを返します。それは、サブプロトコルのネゴシエーションを遂行するために、コンストラクタの第二引数の配列形式と組み合わせて使われることがあります。

close() メソッドは、次の手順を実行しなければいけません:

  1. このメソッドの第一引数は存在するけれども、1000 に等しい、または、3000 ~ 4999 の範囲にある整数でなければ、 INVALID_ACCESS_ERR 例外を投げ、これらの手順を中止します。

  2. このメソッドの第二引数に非対サロゲートが含まれていれば、SYNTAX_ERR 例外を投げ、これらの手順を中止します。

  3. このメソッドの第二引数が存在したら、その引数を UTF-8 としてエンコードした結果を、reason とします。reason が 123 バイトより長かったら、SYNTAX_ERR 例外を投げ、これらの手順を中止します。

  4. 次のリストのうち最初に一致する手順を実行します:

    readyState 属性が CLOSING (2) か CLOSED (3) 状態にある場合

    何もしません。

    コネクションはすでに切断しようとしている最中、または、すでに切断しています。もしまだなのであれば、後述の通り、最終的には close イベントが発出されます。

    WebSocket コネクションがまだ確立していない場合 [WSP]

    WebSocket 接続をあきらめreadyState 属性の値を CLOSING (2) にセットします。 [WSP]

    WebSocket コネクション失敗アルゴリズムは、WebSocket コネクション切断アルゴリズムを呼び出します。これは、WebSocket コネクション切断を確立します。これによって、後述の通りclose イベントが発出されます。

    WebSocket 切断ハンドシェイクがまだ開始されていない場合 [WSP]

    WebSocket 切断ハンドシェイクを開始し、readyState 属性の値を CLOSING (2) にセットします。 [WSP]

    第一引数が存在したら、WebSocket 切断メッセージに使うステータス・コードは、第一引数に指定された整数としなければいけません。 [WSP]

    第二引数も存在したら、切断メッセージ内に、ステータス・コードの後ろに reason を加えなければいけません。 [RFC3629] [WSP]

    WebSocket 切断ハンドシェイク開始アルゴリズムは、最終的に、WebSocket コネクション切断アルゴリズムを呼び出すことになります。これによって、WebSocket コネクション切断が確立され、そして、後述の通りclose イベントが発出されます。

    いずれにも該当しない場合

    readyState 属性の値を CLOSING (2) にセットします。

    WebSocket 切断ハンドシェイクが開始され、そして、最終的に、WebSocket コネクション切断アルゴリズムが呼び出されます。これによって、WebSocket コネクション切断が確立されます。ゆえに、後述の通りclose イベントが発出されます。


bufferedAmount 属性は、アプリケーション・データ(UTF-8 テキストやバイナリー・データ)のバイト数を返さなければいけません。これは、send() を使ってキューイングされたものですが、イベント・ループがタスク実行を開始した最後の時点で、ネットワークにまだ送出されていないものです。(従って、これは、ユーザーエージェントがスクリプト実行と非同期にテキストを転送できるかどうかにかかわらず、現在のタスクの実行中に送信されたテキストを含みます。) これは、プロトコルによって発生するフレーミングのオーバーヘッドや、オペレーティング・システムやネットワーク・ハードウェアによって行われたバッファリングを含みません。コネクションが切断されたら、この属性の値は、send() メソッが呼び出されるごとに増えるだけです(この数値は、コネクションが切断されてもゼロにリセットされません)。

この簡単な例では、ネットワークが耐えられるのであれば、50ms ごとの頻度で 1 回の更新を送信できるのか、または、もし早すぎるなら、どの頻度ならネットワーク耐えられるのか、を確認するために bufferedAmount 属性が使われています。

var socket = new WebSocket('ws://game.example.com:12010/updates');
socket.onopen = function () {
  setInterval(function() {
    if (socket.bufferedAmount == 0)
      socket.send(getUpdateData());
  }, 50);
};

ネットワークが耐えられる以上の頻度でデータを送信しなくても、bufferedAmount 属性を使えば、そのネットワークを飽和状態にすることもできます。ただし、その属性の値を常に注意深くモニタリングしなければいけません。


WebSocket オブジェクトが生成されるとき、その binaryType IDL 属性は文字列 "blob" にセットされなければいけません。取得時には、それがセットされた最後の値を返さなければいけません。セット時には、新たな値が文字列 "blob" か文字列 "arraybuffer" のいずれかであれば、その新たな値をこの IDL 属性にセットしなければいけません。そうでなければ、SYNTAX_ERR 例外を投げなければいけません。

この属性によって、制作者は、スクリプトからバイナリー・データの扱い方をコントロールすることができるようになります。この属性に "blob" をセットすれば、Blob 形式でバイナリー・データが返されます。そして、"arraybuffer" をセットすれば、ArrayBuffer 形式で返されます。ユーザーエージェントは、受信するバイナリー・データの扱い方のヒントとして、これを使うことができます。この属性が "blob" にセットされていれば、ディスクにそれをスプールしても安全です。"arraybuffer" にセットされていれば、メモリーにそのデータを保持しておく方が効率的かもしれません。当然ながら、ユーザーエージェントは、受信するデータをメモリーに保持すべきかどうかを決定するために、もう少し経験則を使うことが推奨されます。例えば、データの大きさを基準にしたり、直前にこの属性を変更することはスクリプトにとってどれくらい一般的なことなのかを基準にすることもできます。この後者の側面は特に重要です。なぜなら、ユーザーエージェントがデータを受信した後ではあるけれども、ユーザーエージェントがそれに対するイベントを発出する前に、この属性が変更される可能性が十分にあるからです。

send(data) メソッドは、コネクションを使ってデータを送出します。readyState 属性が CONNECTING なら、INVALID_STATE_ERR 例外を発出しなければいけません。そうでなければ、ユーザーエージェントは、次のリストの中から適切な手順を実行しなければいけません:

引数が文字列の場合

data 引数が非対サロゲートを含んでいたら、SYNTAX_ERR 例外を発出します。WebSocket コネクションが確立し、その文字列に非対サロゲートが含まれておらず、WebSocket 切断ハンドシェイクがまだ開始されていなければ、ユーザーエージェントは、テキスト・フレーム opcode を使って data から構成された WebSocket Message を送信しなければいけません。バッファする必要があるのにバッファが一杯だったなどの理由で、データを送信できなかったら、ユーザーエージェントは、無条件にWebSocket コネクションを切断しなければいけません。例外を発しない文字列の引数とともにこのメソッドが呼び出されたら、その引数を UTF-8 として表現するに必要なバイト数だけ、bufferedAmount 属性を増やさなければいけません。 [RFC3629] [WSP]

引数が Blob オブジェクトの場合

WebSocket コネクションが確立し、WebSocket 切断ハンドシェイクがまだ開始されていなければ、ユーザーエージェントは、バイナリー・フレーム opcode を使って、data から構成された WebSocket Message を送信しなければいけません。バッファする必要があるのにバッファが一杯だったなどの理由で、データを送信できなかったら、ユーザーエージェントは、無条件にWebSocket コネクションを切断しなければいけません。。送信すべきデータは、Blob オブジェクトによって表される生データです。例外を発しない Blob 引数とともにこのメソッドが呼び出されたら、その Blob オブジェクトの生データのサイズのバイト数だけ、bufferedAmount 属性を増やさなければいけません。 [WSP] [FILEAPI]

引数が ArrayBuffer オブジェクトの場合

WebSocket コネクションが確立し、WebSocket 切断ハンドシェイクがまだ開始されていなければ、ユーザーエージェントは、バイナリー・フレーム opcode を使って、data から構成された WebSocket Message を送信しなければいけませんバッファする必要があるのにバッファが一杯だったなどの理由で、データを送信できなかったら、ユーザーエージェントは、無条件にWebSocket コネクションを切断しなければいけません。送信すべきデータは、ArrayBuffer オブジェクトによって記述されたバッファ蓄積データです。例外を発しない ArrayBuffer 引数とともにこのメソッドが呼び出されたら、その ArrayBuffer オブジェクトの長さだけ、bufferedAmount 属性を増やさなければいけません。 [WSP] [TYPEDARRAY]


WebSocket インタフェースを持つすべてのオブジェクトが IDL 属性としてサポートしなければいけないイベント・ハンドラは次の通りです:

イベント・ハンドラ イベント・ハンドラ・イベント・タイプ
onopen open
onmessage message
onerror error
onclose close

5 プロトコルからのフィードバック

WebSocket コネクションが確立されたら、ユーザーエージェントは次の手順を実行するタスクをキューイングしなければいけません:

  1. readyState 属性の値を OPEN (1) に変更します。

  2. extensions 属性の値を、使用中の拡張に変更します。ただし、その値が null でない場合に限ります。 [WSP]

  3. protocol 属性の値を、使用中のサブプロトコルに変更します。ただし、その値が null でない場合に限ります。 [WSP]

  4. ユーザーエージェントが、WebSocket() コンストラクタに指定された URL url に対して、サーバーの接続開始ハンドシェイクの間にセットされる cookie のセットから構成される set-cookie-string を受信したかのように振る舞います。 [COOKIES] [RFC3629] [WSP]

  5. WebSocket オブジェクトで open という名前のシンプルなイベントを発出します。


type type と data data とともに WebSocket メッセージを受信したら、ユーザーエージェントは、次の手順に従って、タスクをキューイングしなければいけません: [WSP]

  1. readyState 属性の値が OPEN (1) でも CLOSING (2) でもなければ、これらの手順を中止します。

  2. event を、MessageEvent インタフェースを使うイベントとします。イベント名は message で、バブリングせず、キャンセルできず、デフォルト・アクションを持ちません。

  3. eventorigin 属性を、WebSocket オブジェクトのコンストラクタに引き渡された URL のオリジンの Unicode シリアライゼーションに初期化します。

  4. type がデータは Text だと示すなら、eventdata 属性を data に初期化します。

    type がデータは Binary だと示し、binaryType が "blob" にセットされているなら、eventdata 属性を、data をその生データとして表す新たな Blob オブジェクトに初期化します。 [FILEAPI]

    type がデータは Binary だと示し、binaryType が "arraybuffer" にセットされているなら、eventdata 属性を、コンテンツが data となる新たな読み取り専用の ArrayBuffer オブジェクトに初期化します。 [TYPEDARRAY]

  5. WebSocket オブジェクトで event を発出します。

ユーザーエージェントは、タスクを実行する前に、効率的に前述の手順を実行できるかどうかをチェックすることが推奨されます。他のタスク・キューからタスクを取り出して、その一方で、できないなら、バッファを準備するのです。例えば、データが到着したときに binaryType 属性が "blob" にセットされており、ユーザーエージェントがすべてのデータをディスクへスプールしたけれども、この特定のメッセージに対して前述のタスクを実行する直前に、スクリプトが binaryType から "arraybuffer" に切り替えたとしたら、ユーザーエージェントは、メイン・スレッドがストールしないよう、このタスクを実行する前に、データを RAM に戻して、ArrayBuffer オブジェクトを生成したいと考えるでしょう。


WebSocket 切断ハンドシェイクが開始されるとき、ユーザーエージェントは、readyState 属性の値を CLOSING (2) に変更するタスクをキューイングしなければいけません。(close() メソッドが呼び出されたのであれば、readyState 属性の値は、このタスクが実行されているときにはすでに CLOSING (2) にセットされているでしょう。) [WSP]


WebSocket コネクションが切断されるとき、ユーザーエージェントは、できる限り手際よく、次の副手順を実行するタスクをキューイングしなければいけません:

  1. readyState 属性の値を CLOSED (3) に変更します。

  2. ユーザーエージェントが、WebSocket コネクションを失敗とする必要があった、または、WebSocket コネクションが無条件に切断されるなら、WebSocket オブジェクトで error という名前のシンプルなイベントを発出します。 [WSP]

  3. CloseEvent インタフェースを使うイベントを生成します。イベント名は close で、バブリングせず、キャンセルできず、デフォルト・アクションはありません。その wasClean 属性は、コネクションが完全に切断されているなら true で、そうでなければ、false で初期化されます。その code 属性は、WebSocket コネクション切断コードで初期化されます。その reason 属性は、WebSocket コネクション切断理由を UTF-8 でデコードしたもので初期化されます。そして、エラー・ハンドリングを伴って、WebSocket オブジェクトでこのイベントを発出します。 [WSP]

このセクションでキューイングされるタスクすべてに対するタスク・ソースは、WebSocket タスク・ソースです。

5.1 イベント定義

[Constructor(DOMString type, optional CloseEventInit eventInitDict)]
interface CloseEvent : Event {
  readonly attribute boolean wasClean;
  readonly attribute unsigned short code;
  readonly attribute DOMString reason;
};

dictionary CloseEventInit : EventInit {
  boolean wasClean;
  unsigned short code;
  DOMString reason;
};

wasClean 属性は、それが初期化されたときの値を返さなければいけません。オブジェクトが生成されるとき、この属性は false に初期化されなければいけません。これは、コネクションが完全に切断されているかどうかを表します。

code 属性は、それが初期化されたときの値を返さなければいけません。オブジェクトが生成されるとき、この属性はゼロで初期化されなければいけません。これは、サーバーから得られた WebSocket コネクション切断コードを表します。

reason 属性は、それが初期化されたときの値を返さなければいけません。オブジェクトが生成されるとき、この属性は空文字列で初期化されなければいけません。これは、サーバーから得られた WebSocket コネクション切断理由を表します。

5.2 ガーベッジ・コレクション

イベント・ループがタスクの実行を開始した最後の時点で readyState 属性の値が CONNECTING (0) にセットされた WebSocket オブジェクトは、open イベント、message イベント、error イベント、close イベントに対して登録されたイベント・リスナーが一つでもあれば、ガーベッジ・コレクションの対象になってはいけません。

イベント・ループがタスクの実行を開始した最後の時点で readyState 属性の値が OPEN (1) または CLOSING (2) にセットされた WebSocket オブジェクトは、message イベント、error イベント、error イベントに対して登録されたイベント・リスナーが一つでもあれば、ガーベッジ・コレクションの対象になってはいけません。

ネットワークへの送出のためにキューイングされたデータを持つ確立済みのコネクションを伴う WebSocket オブジェクトは、ガーベッジ・コレクションの対象になってはいけません。 [WSP]

WebSocket オブジェクトが、そのコネクションがまだ開いているのにガーベッジ・コレクションの対象になってしまったら、ユーザーエージェントは、 WebSocket 切断ハンドシェイクを開始しなければいけません。切断メッセージに対するステータス・コードはありません。 [WSP]


ユーザーエージェントが WebSocket オブジェクトを消滅させることになったら(これは、Document オブジェクトが無くなってしまったときに起こります)、ユーザーエージェントは次のリストのうち最初に該当するものに従わなければいけません:

WebSocket コネクションがまだ確立されていない場合 [WSP]

WebSocket コネクションを失敗とします[WSP]

WebSocket 切断ハンドシェイクがまだ開始されていない場合 [WSP]

WebSocket 切断ハンドシェイクを開始します。WebSocket 切断メッセージに使うステータス・コードは 1001 とします。 [WSP]

Otherwise

何もしません。

References

"非規定" とマークされていない限り、すべてのリファレンスが規定です。

[COOKIES]
HTTP State Management Mechanism, A. Barth. IETF.
[DOMCORE]
Web DOM Core, A. van Kesteren. W3C.
[FILEAPI]
File API, A. Ranganathan. W3C.
[HTML]
HTML5, I. Hickson. W3C.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF.
[RFC3629]
UTF-8, a transformation format of ISO 10646, F. Yergeau. IETF.
[TYPEDARRAY]
Typed Array Specification, D. Herman, K. Russell. Khronos.
[WEBIDL]
Web IDL, C. McCormack. W3C.
[WSP]
The WebSocket protocol, I. Fette. IETF.

謝辞

謝辞の完全なリストは、HTML 仕様をご覧ください。 [HTML]