Firefox における WebSockets

WebSockets の要点:低い複雑性、小さなレイテンシ、Web 開発者のためのとてもシンプルな API を持った双方向の通信方式。

WebSocket の特徴をもう少し詳しく説明した後、Firefox 上に実装するのかどうか、そしてそれはいつ頃になるのかについて話をしてみよう。

低い複雑性

HTTP のようなハンドシェイクから始まる WebSocket プロトコルは、テキストパケットを相互に送受信するための、比較的シンプルなモデルを持っている。プロトコルは極めて簡素だ。多重通信やバイナリデータはサポートせず、一度コネクションが確立すると、実際のデータ転送コストはとても低くなる。

ただし、多重通信やバイナリデータもサポートすべきと考える人たちもいる(彼らが正しいかもしれない)。それが複雑性を高めることは明白だが、それに見合うケースだってありうる。これについては後述する。

双方向通信

WebSocket の主な特徴に、シンプルな相互通信のサポートが挙げられる。
サーバはクライアントへの更新情報を、クライアントはサーバへの更新情報を、各々容易に送ることができる。
以前から開発されてきた Comet によるアプリケーションの多くはこのモデルにより、ずっとシンプルで高速になるだろう。プロトコルと API が直接にそれをサポートしているためだ。

相互通信を可能とする一方で、HTTP による same-origin モデルの制約は受ける。
つまり、ブラウザに対して任意のサイトの任意のポートに接続するような能力を、WebSocket が与えることはない。

要するに、WebSocket は HTTP のセキュリティモデルを備えた TCP といったところだ。

低いレイテンシ

実のところ、これが WebSocket 最大の利点だ。少量のデータを送るコストがとても小さいことが鍵だ。
現在でも Comet を用いれば相互通信が可能だが、そこではわずかなデータを送るために、大きなオーバーヘッドが必要となっていることも多い。

スケールの感覚を理解してもらうために、少々間接的な話をしてみよう。Google Wave では、キー入力にあわせたリアルタイム通信に挑戦している。そのため、キーストロークごとに数 KB のオーバーヘッドが発生している。原因は、TCP通信の開始(startup)、接続の裂け目(teardown)、たった数 byte であるべき時にも必ず含まれる HTTP メッセージヘッダが送信されるからだ。

私自身は挑戦したことはないが、こう推測している。もしあなたが Quake を HTTP Comet で実装すれば、その応答性は貧弱なものになるだろう。これこそが、WebSockets が本当に力を発揮する分野だ。

シンプルなAPI

開発者が WebSocket で用いる実際の API は比較的シンプルなものだ。メッセージを送信することができ、メッセージを取得することができる。ソケットがオープンしたとき、クローズしたとき、エラーが起きたときにイベントを取得する。JavaScript とバックエンドのライブラリにはまだ、今後機能が追加されるのは間違いないだろう。

(こう聞くと複雑な問題は後回しにしているようだが、実のところこれが、他のブラウザ関連の標準で目にしてきた成功への道なのだ。まずはみんなが試してみられる比較的単純なものを作る。そして何が遅いのか、何が進歩を妨げるのかを理解したら改良を繰り返していくのです。)

いつFirefox に実装されるのか

次期バージョンの Firefox で、ぜひとも WebSockets に対応したい。多くの人たちも、私たちがそうするのを望んでいる。

素晴らしい Wellington Fernando de Macedo (最も素晴らしい貢献者の一人)によって書かれた最初のテストパッチのセットは、2009年4月に最初にサブミットされた。それから、私たちはパッチをあてることと、変更された仕様への対応とを繰り返し続けている。

不運にも、仕様自身がまだ改訂中だ。
WebSockets は Chrome 4に搭載され、Chrome 5 にもそのまま変更なしに含められる予定だと Chrome 開発者に聞いている。
本当に不運なことに、Google が Chrome に採用したバージョンは、現在のドラフトを反映できていない。
WebSocket 接続をどのように開始するのかを決めるハンドシェイク方法が変更されている。これはサーバ上のセキュリティを大きく改良するためのものだ。

まだ多くの進行中の議論がある。圧縮機能の統合をどうするか、(バイナリを文字列にエンコードするのでなく)バイナリデータの直接サポートについて、多重通信をサポートすべきか否かについて、そして、その他の多くの課題について。

WebSocket はまだ広く使われておらず、Chrome の仕様追従速度も Firefox と大差ない。より新しい仕様のドラフトが通過したら、Chrome と Firefox が共に新しいバージョンの仕様を同時期にサポートするようになれば望ましいと考えている。

簡潔にまとめると:WebSocket の前途は素晴らしいものだから、私たちはそれに対応したい。しかし、それが十分に安定、安全なものなのか私たちは見定める必要がある。
コードが問題なのではない。私たちはそれを以前から持っている。数億人の人々に対してソフトウェアをリリースするために、プロトコルが「十分に完成されている」のか、コンセンサスがあるか否かが重要なのだ。

3 件のコメント

  1. dynamis :

    誤訳箇所など気になるところなど勝手に修正しました。

    ページリビジョンの差分を確認して、おかしければまた適当に直してください:
    https://dev.mozilla.jp/wp-admin/revision.php?action=diff&right=3162&left=3178

  2. Masayuki HIGASHINO :

    1年以上も前の記事にコメントするのもなんですが、

    > スケールの感覚を理解してもらうために、少々間接的な話をしてみよう。
    > Google Wave では、キー入力にあわせたリアルタイム通信に挑戦している。
    > そのため、キーストロークごとに数 KB のオーバーヘッドが発生している。
    > 原因は、TCP通信の開始(startup)、接続の裂け目(teardown)、たった
    > 数 byte であるべき時にも必ず含まれる HTTP メッセージヘッダが送信さ
    > れるからだ。

    ここはHTTPサーバの実装の問題ではないでしょうか。
    HTTP POSTのリクエストヘッダでContent-Lengthの値を大きくしてやれば、
    その値を越えるまでキーストロークのデータをストリーミングで送信できるはずです。

  3. dynamis :

    コメントありがとうございます。

    サーバ間の通信であればそうかもしれませんが、ブラウザの JS とサーバの通信においては XMLHttpRequest を使うことになりますよね?Multipart Ajax が使えれば受信については少しずつ順次ということも可能ですが、送信については XMLHttpRequest はそのようなデータ送信方法をサポートしておらず不可能ではないでしょうか。
    # Wave の実装やその設計方針については知りません