概要
Web Sockets は、JavaScriptからサーバーとの双方向通信を行いメッセージ交換を実現するAPIです。XHRでは実現できなかったようなリアルタイムの対話が実現できますので、これまでには無かった新しいウェブアプリケーションを予感できます。
現在はW3CのHTML5仕様から分離されてしまいましたが、次世代のウェブアプリケーションの中核を担うテクノロジーとして期待されています。
一部、直訳ではなく意訳した部分がございます。原文と表現が異なることがございますので、ご了承ください。この日本語訳は、私が理解を深めるために、自分なりに日本語化したものです。本日本語訳には、翻訳上の誤りがある可能性があります。したがって、内容について一切保証をするものではありません。正確さを求める場合には、必ず原文を参照してください。当方は、この文書によって利用者が被るいかなる損害の責任を負いません。もし誤りなどを見つけたら、当サイトのお問い合わせより連絡いただければ幸いです。
Web Sockets は、JavaScriptからサーバーとの双方向通信を行いメッセージ交換を実現するAPIです。XHRでは実現できなかったようなリアルタイムの対話が実現できますので、これまでには無かった新しいウェブアプリケーションを予感できます。
現在はW3CのHTML5仕様から分離されてしまいましたが、次世代のウェブアプリケーションの中核を担うテクノロジーとして期待されています。
Copyright © 2009 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
The text of this specification is also available in the WHATWG Web Applications 1.0 specification, under a license that permits reuse of the specification text.
この仕様では、ウェブページがリモートホストとの双方向通信のために Web Sockets プロトコルを使えるようにする API を定義しています。
このセクションでは、発行時における本文書の状態を説明します。本文書は他の文書によって置き換えられるかもしれません。現在のW3Cの発行物と、この技術に関するレポートの最新の公式の公開リビジョンの一覧は、http://www.w3.org/TR/ の W3C technical reports index をご覧ください。
コメントがあれば、public-webapps@w3.org (subscribe, archives), whatwg@whatwg.org (subscribe, archives), hybi@ietf.org (subscribe, archives) に送ってください。どんなフィードバックでも歓迎です。
実装者は、この仕様はまだ安定していないということを承知するべきです。この議論に参加していない実装者は、この仕様を逸脱して、互換性がなくなってしまうような解釈をしてしまうかもしれません。勧告候補の段階に達する前に、この仕様の実装に興味を持ったベンダーは、前述のメーリングリストに加わって、議論に参加するべきです。
この仕様の editor's draft の最新の安定バージョンは、W3CのCVSサーバーからいつでも入手可能です。この文書の変更履歴は、次の場所から入手可能です:
この仕様は、HTML5 仕様ソース・ドキュメントにある対応のセクションから自動的に生成されたものです。それは、WHATWG Subversion repository にホスティングされているものです。HTML5 全体の変更履歴の詳細は、この仕様を構成する部分も含めて、次の場所から入手可能です:
W3C の Web Apps ワーキンググループは、W3C 勧告トラックに沿ってこの仕様の進捗に責任を持つW3Cワーキンググループです。この仕様は、2009-12-01 Editor's Draft です。
この仕様は、有線プロトコルや Web Socket プロトコルのための Internet Draft と連動して開発されています。これらは IETF から次の場所で入手可能です:
本文書は、5 February 2004 W3C Patent Policy に基づき運営するグループによって作られました。W3C は、グループの成果物に関連して作られた public list of any patent disclosures をメンテナンスしています。そのページには、特許を開示する方法も掲載されています。Essential Claim(s) を含むと信じる特許の実知識を持つ個人は、section 6 of the W3C Patent Policy に従って情報を開示しなければいけません。
このセクションは非規定です。
ウェブ・アプリケーションからサーバー側の処理と双方向通信ができるようにするために、この仕様では WebSocket インタフェースを紹介します。
このインタフェースから下層ネットワークに対して直接アクセスすることはできません。例えば、このインタフェースは IRC クライアントを実装するために使うことはできないでしょう。メッセージを独自サーバーに通してプロクシしなければいけないでしょう。
この仕様では、それぞれの節で非規定と記載されていれば、その節にある図表や例や注意事項はすべて非規定です。それ以外はすべて規定です。
この仕様の規定部分にある "しなければいけない(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 攻撃を防止するためや、メモリーオーバーを防ぐためや、プラットフォーム固有の制限に対する回避策などです。
この仕様は、いくつかの下層の仕様に依存しています。
"Foo オブジェクト" といったら、 Foo が実際にインタフェースになるのですが、ときどき、さらに正確に "Foo インタフェースを実装したオブジェクト" という言い方が代わりに使われることがあります。
DOM という用語は、ウェブ・アプリケーションでスクリプトから利用できるようにセットされている API を参照するために使われますが、必ずしも、DOM Core 仕様で定義されているような Document オブジェクトや他の Node オブジェクトが実際に存在することを意味しているわけではありません。[DOMCORE]
IDL 属性は、その値が取り出されているときには(例えば、ウェブ制作者側のスクリプトによって)、"取得される"と言い、それに新しい値が割り当てられるときには、"セットされる"と言います。
WebSocket インタフェース[Constructor(in DOMString url, in optional DOMString protocol)] interface WebSocket { readonly attribute DOMString URL; // ready state const unsigned short CONNECTING = 0; const unsigned short OPEN = 1; const unsigned short CLOSED = 2; readonly attribute unsigned short readyState; readonly attribute unsigned long bufferedAmount; // networking attribute Function onopen; attribute Function onmessage; attribute Function onclose; boolean send(in DOMString data); void close(); }; WebSocket implements EventTarget;
WebSocket(url, protocol) コンストラクタは、1 つか 2 つの引数を取ります。第 1 引数 url には、どこに接続するのかを表す URL を指定します。第 2 引数 protocol は、もし指定するなら、サーバーが接続を成功させるためにサポートしなければいけないサブ・プロトコルを指定します。そのサブ・プロトコルの名前は ASCII 文字列でなければいけません。ただし、U+000A LINE FEED (LF) および U+000D CARRIAGE RETURN (CR) 文字を入れることはできません。
WebSocket()コンストラクタが呼び出されたら、ユーザーエージェントは次の手順を実行しなければいけません:
url 引数からの Web Socket の URL コンポーネントをパースして、host, port, resource name, secure を取得します。これが失敗したら、SYNTAX_ERR 例外を投げ、これらの手順を中止します。
port がユーザーエージェントによってアクセスをブロックするよう設定されているポートなら、SECURITY_ERR 例外を投げます。(通常、ユーザーエージェントは SMTP のような well-known ポートへのアクセスをブロックします)
protocol が存在しているものの、U+007F より大きい Unicode コード・ポイントを伴う文字(つまり非 ASCII 文字のこと)を含んでいるなら、 または、それが U+000A LINE FEED (LF) 文字 や U+000D CARRIAGE RETURN (CR) 文字のいずれかを含んでいるなら、SYNTAX_ERR 例外を投げ、これらの手順を中止します。
origin を、WebSocket() コンストラクタを呼び出したスクリプトの origin の ASCII シリアライゼーションとします。ただし、小文字に変換されたものとします。
新しい WebSocket オブジェクトを返し、バックグラウンドで、こららの手順を継続します(スクリプトをブロッキングしません)。
ホスト host に、ポート port で(指定されれば)、origin から、フラグ secure を付け、リソース名として resource name を付け、プロトコルとして protocol を付けて(存在すれば)、Web Socket コネクションを確立します。
もし、"Web Socket コネクションを確立する" アルゴリズムが失敗したら、"Web Socket コネクションに失敗する" アルゴリズムが呼び出されます。これは、後述の通り、"Web Socket コネクションが閉塞される" を呼び出し、その後、"Web Socket コネクションを閉塞する" を確立し、close イベントを発出します。
スクリプトのグローバル・オブジェクトが Window オブジェクトや WorkerUtils インタフェースを実装するオブジェクトのいずれかとなるときには、このコンストラクタが見えるようにしなければいけません。
URL 属性は、コンストラクタに引数として渡された URL の解決した結果を返さなければいけません。 (それが、どこを相対基準として解決されたのかについては問題ではありません。なぜなら、それはすでに絶対 URL だと分かっているからです。)
readyState 属性は、コネクションの状態を表します。これは次の値を取ります:
CONNECTING (数値の 0)OPEN (数値の 1)CLOSED (数値の 2)オブジェクト生成時、その readyState には CONNECTING (0) がセットされなければいけません。
send(data) メソッドは、コネクションを使ってデータを送信します。コネクションがまだ確立されていないなら(readyState が CONNECTING)、INVALID_STATE_ERR 例外を発出しなければいけません。(一度、コネクションが確立されたものの、その後、閉塞されてしまったなら、例外は発出されません) もし引数 data に非サロゲートペアがあれば、SYNTAX_ERR を発出しなければいけません。もしコネクションが確立され、その文字列に非サロゲートペアがなければ、ユーザーエージェントは Web Socket を使って data を送信しなければけません。もし、バッファの必要があったけれどもバッファが一杯だったなどの理由で、そのデータが送信できなかったなら、ユーザーエージェントは、その Web Socket コネクションを閉塞しなければいけません。このメソッドは、そのコネクションがまだ確立されている(そのデータがキューイングされ、送信が成功した)なら true を、そのコネクションが閉塞されている(例えば、ユーザーエージェントがバッファ・オーバーフローになり、データの送信に失敗したといった理由で)なら false を返さなければいけません。
close() メソッドは、Web Socket コネクションや、接続を試みているコネクションがあれば、それを閉塞しなければいけません。そのコネクションがすでに閉塞されていれば、何もしてはいけません。
後述の通り、最終的にコネクションを閉塞すると、close イベントが発生し、readyState 属性の値が変更されることになります。
bufferedAmount 属性は、キューイングされたものの、まだ送信されていないバイト数を返さなければいけません。そのコネクションが閉塞されても、この属性の値は、send()メソッドの呼び出しとともに増えていくだけとなります(その数値は、そのコネクションが閉塞しても、0 にリセットされることはありません)。
下表は、WebSocket インタフェースを実装するすべてのオブジェクトで、IDL 属性として、サポートされなければいけないイベントハンドラ属性です:
| イベント・ハンドラ | イベント・ハンドラのイベント・タイプ |
|---|---|
onopen |
open |
onmessage |
message |
onclose |
close |
Web Socket コネクションが確立したとき、ユーザーエージェントは次の手順を実行しなければいけません:
readyState 属性の値を OPEN (1) に変更します。
WebSocket オブジェクトで open とう名前のシンプルなイベントを発出するタスクをキューイングします。
Web Socket メッセージをテキスト data で受信したら、ユーザーエージェントは、MessageEvent インタフェースを使うイベントを生成しなければいけません。このイベントは、イベント名が message で、バブリングせず、cancelableではなく、デフォルト・アクションを持たず、data が data 属性にセットされ、WebSocket オブジェクトでそれを送出するタスクをキューイングします。
Web Socket コネクションが閉塞されたとき、readyState 属性の値は CLOSED (2) に変更されなければいけません。そして、ユーザーエージェントは、WebSocket オブジェクトで close という名のシンプルなイベントを発出するタスクをキューイングしなければいけません。
このセクションでキューイングされたすべてのタスクに対するタスクソースは、Web Socket タスク・ソースとなります。
開いたコネクションを持つ WebSocket オブジェクトは、message イベントに対して登録されたイベントリスナがあれば、ガーベッジ・コレクションの対象としてはいけません。
WebSocket オブジェクトが、コネクションが開いているにもかかわらず、ガーベッジ・コレクションの対象となってしまったら、ユーザーエージェントは、その Web Socket コネクションを閉塞しなければいけません。
"非規定" とマークされていない限り、すべてのリファレンスが規定です。