BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース HTML 5 Web Sockets vs. Comet and Ajax

HTML 5 Web Sockets vs. Comet and Ajax

ブックマーク

World Wide Webは90年代半ばに急速に成長し、情報分散の一番の手段となった。そしてブラウザがユビキタスになりユーザがそれを使うことに慣れてくれば、歴史上のどんなプラットフォームのユーザ数よりも多いユーザが利用するアプリケーションプラットフォームになることは明らかだ。しかし今はHTMLやHTTPなどの標準が、高度なインタラクションや優れたユーザエクスペリエンスといった考え方を元々の設計思想に持ってないため、まだその段階には至っていない。多機能なオンラインアプリケーションを提供しようとする初期の取り組みのいくつかは、MicrosoftのExchangeエンジニアチームでされていた。このチームはメールサーバのフロントエンドをOutlookに似たものにするために96年からIFrame要素を使っていた。当時はそれが応答性や全般的なユーザエクスペリエンスを妨げるものになっていたが、しかし来るべき潮流の明らかな兆しだった。このチームが1998年にMS Exchange Server 2000用のウェブフロントエンドを作り始めたときに作ったのがXMLHTTPだ。これは単一のウェブページからサーバに非同期の通信をおこなうようにするコンポーネントだ。このXMLHTTPはXMLに限定されているわけではない。XMLHTTPは当時このチームの一員だったAlex Hopmann氏によって提唱されたものだが、XMLという言葉が頭に付けられたのは、ベータ2が出ようとしていたIE 5がMS XMLライブラリの一部としてリリースされることになっていたためだ。

この新しい技術はMozilla FoundationでもXMLHttpRequest(XHR)として、その後Firefoxとなるブラウザの最初のバージョンに2002年実装された。他のベンダはこの新しいAPI群の力を活用しようと試みたが、その理論的枠組みとなるリモートスクリプティングという考えは、Googleが JavaScriptとXHRをベースにした一連の次世代サービスを公開して一躍注目を集めるようになるまで公に意識されることはなかった。Google サービスの第一弾はGoogle Mapsだった。これが最初に表に現れたのは2005年2月8日のGoogle Blogでだった。XHRはその後たった数ヶ月でこの業界の一番ホットな技術となった。この時はまだ誰もはっきりとXHRがウェブアプリケーション開発にもたらす革命を予見できたわけでないが、それが我々のWWWに対する考えを変えていくであろうことは疑う余地がなかった。

今度Kaazing Gateway(リンク)がリリースされたのを期に、InfoQはAjax (参考記事リンク)やComet(参考記事リンク)、そして期待されているHTML 5 Web sockets(リンク)といった技術に関する進展についてRichard Allen氏と話をした。

Ajax はHTTP通信モデルの潤滑剤で、クライアントが非同期にサーバサイドのイベントをポーリングできるようにします。ポーリングとは一定間隔でサーバイベントをブラウザのキューへ登録することで、そのことでサーバからの通信をエミュレートしポーリング間隔分のメッセージをリアルタイムに配信することができます。ですから、本当の意味でのリアルタイム通信はツールとしてのAjaxだけではどうしてもできません。

CometもHTTP通信モデルからの脱却において同じくらい画期的なもので、オーバーHTTPで「プッシュ」方式の通信をする方法です。Cometはクライアントからの要求なしにサーバから情報をブラウザに送るためのいくつかのテクニックを定義しています。Cometは、1 つ余分に設けられたHTTP接続を利用することで、2つのHTTP接続による双方向の通信をすることもできます。しかし、Cometの問題点はその構成パーツとなるXHRとIFrameについてのサポートがブラウザのベンダによってまちまちで、標準的な実装がないことです。さらにCometでは通信のために2つの接続を使うので、その管理はネットワークと開発の両方でかなりの負荷となります。そのため、Cometアプリケーションで実現できるリアルタイム通信の精度の制限としてレイテンシが設けられることがあります。

HTML 5のWebSocketは、HTTP通信でやれることは何でもやってしまおうという試みの歴史においてCometとAjaxに次ぐ進化となります。 HTML 5 WebSocketの仕様はブラウザとサーバの間で情報をプッシュしたりプルしたりするための単一ソケットによる双方向接続を定義しています。それにより Cometの接続とポータビリティの問題を回避し、Ajaxより効率的にポーリングをおこなうことができます。今の時点では、ウェブにおいて双方向通信をリアルタイムにおこなう仕組みとしてはHTML 5 Web socketsが一番優れています。

氏はAjaxやCometにはいくつもの制約があると感じている。

Ajaxでサーバが起点となっているように通信をシミュレートするにはポーリングの仕組みが必要になり、アプリケーションの状態が変化しているしていないにかかわらず何かあったかをチェックしにいくことになります。その結果CPUサイクルやメモリがサーバの変更を検知する前から、あるいは後になって不必要に割り当てられるので、クライアントでもサーバでもリソースの利用が非効率になります。こうしたことから、従来のAjaxアプリケーションは、サーバでどれだけの割合でイベントが起きるかに応じて、リクエストグループごとにポーリングの間隔を短くしたり長くしたりと常にうまくバランスを取るようにしないといけません。さらに、ポーリングの回数が増えるとネットワークトラフィックとサーバへの要求が大きくなり、逆に減らすと変更の検知を逸したり古い情報が送られることがおきます。どちらの場合も、メッセージ配信で余計な待ち時間が発生します。その上、短い間隔でポーリングでおこなう場合。規模が大きくなるとpingによってサーバのリソースが大量に消費されることでコストが高くなります。

Comet はサーバとブラウザの間で長時間の接続、あるいは長時間持続するHTTPリクエストを維持することで「プッシュ」通信をおこなおうとします。この接続によりクライアントから発生する通信を利用してサーバからブラウザへイベントを送信できるようにするものです。ブラウザからサーバへのリクエスト自体は別に設けられたHTTP接続によって送信されます。このようにCometでは双方向の通信を2つのHTTP接続によっておこなうことができます。しかし、この2 つの接続を維持管理することはひとつのクライアントに対して2倍のリソースを用意することになるため、サーバでのリソース使用の点で大きな負荷となります。その上、HTTPでの接続時間がドメインによって制限されていることはよくあります。このことがCometの使用をより複雑にし、多重送信や複数ドメイン管理といった手間のかかるテクニックが必要になることが多くあります。

Comet の中にはロングポーリングと呼ばれるテクニックによってリソース消費を軽減しようとするものもあります。しかしこのテクニックでは適切とはいえない HTTPリクエストヘッダ/レスポンスヘッダを送ることになります。たとえば、サーバからイベントを送信する時には、サーバはクライアントブラウザとの接続を切断して、ブラウザがサーバへ再度接続するようにさせます。これはポーリングの長い間隔ごとに、新しいクライアントリクエストおよび新しいサーバレスポンスを同じ経路で送ることで実現します。そのレスポンスでは以下のようにしばしばHTTPヘッダの方がメッセージ本体よりも大きくなります。

クライアント(ブラウザ)からサーバへのリクエスト
GET /long-polling HTTP/1.1\r\n
Host: www.kaazing.com\r\n
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9) Gecko/2008061017 Firefox/3.0\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n
Accept-Language: en-us,en;q=0.5\r\n
Accept-Encoding: gzip,deflate\r\n
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n
Keep-Alive: 300\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
\r\n


サーバからクライアント(ブラウザ)へのレスポンス
Date: Tue, 16 Aug 2008 00:00:00 GMT\r\n
Server: Apache/2.2.9 (Unix)\r\n
Content-Type: text/plain\r\n
Content-Length: 12\r\n
\r\n
Hello, world
	

Comet を使った開発には多くの課題があります。独自の解決策を取ることもできます。そのためには永続的な接続を保持するための永久フレームやXHRストリーミングといった数多くのテクニックを用いたJavaScriptライブラリの開発が必要になります。そのようなテクニックを実装する上でブラウザごとに仕様や挙動が異なるのが問題になりますが、さらに悪いことに、JavaScriptのパーツを送るサーバ側のコードにしばしば依存することで、 JavaScriptの複雑さが増すのと同時にポータビリティの問題も絡んできます。

幸い、そのような通信を抽象化することでComet開発をシンプルにするフレームワークが存在します。一番有名なのはSitePenのCometdで、これはBayeux仕様と呼ばれるComet用の発信/受信モデルを定義した仕様のリファレンス実装です。Jettyの最近のバージョンもJavaで作られた Bayeux仕様のサーバサイド実装を含んでいます。

Bayeux とCometdによってCometがシンプルになるのは間違いありません。しかしそのAPIと通信プロトコルに関しては多数の論議があります。Comet Dailyでは「Coliding Comet: Battle of the Bayeux(リンク)(彗星の衝突:バイユーの戦い)」シリーズ(“Coliding Comet: Battle of the Bayuex”)でBayeuxに関する問題を詳しく検証しています。

氏の語るとこでは、HTML 5 Web socketsは今の手法よりも多くの利点をもたらしてくれるという。

Comet やAjaxはどちらもデスクトップのような機能やユーザの気にならない遅延といったユーザエクスペリエンスを提供します。しかし極僅かな遅延でブラウザへ /ブラウザから正確かつ効率的にイベント配信するのを約束できるのはWeb socketsだけです。リアルタイムにウェブで情報を配信するための汎用的な手段としては間違いなくHTML 5 Web socketsが一番です。これは単一のTCP/IP接続で非同期の双方向ストリーミングが完全にできるだけでなく、HTTPヘッダが少なくて済むという利点もあり、さらに重要なのはブラウザからでもサービスからでも同じメッセージフォーマットを使えばすむことです。

Comet 実装のほとんどはBayeuxプロトコルを基にしています。このプロトコルを使うにはサービスからメッセージを送る時にメッセージを元のフォーマットから Bayeuxプロトコルに合うように変換しないといけません。この変換のためには、サーバ側のメッセージフォーマット(JMSやIMAPやXMPPなど)とクライアント側のメッセージフォーマット(BayeuxやJSONなど)を処理するための開発が必要になり、システムを不必要に複雑にしてしまいす。さらに、元のフォーマットからBayeuxのフォーマットに変換するための変換コードは送信前にメッセージをインタプリトして処理する必要があるためにパフォーマンスでも不必要な負荷となります。Web socketsでは、サーバが送信するメッセージはブラウザが受信するメッセージと同一となるため、変換コードのために考慮すべき複雑さやパフォーマンスの問題はなくなります。

Web socketsの有効性に関する疑問はしばしばあります。今の段階ではブラウザはネイティブサポートをしていません。しかしWebKit、 Firefox、Operaといったブラウザが、canvasやpostMessageやオフラインストレージ、Server-sent events(SSE)といったHTML 5の他機能を採用してきたことからすれば、今後数ヶ月のうちに状況が変わるのは確かです。

Web socketsのためには、サーバ側でもある程度サポートがおこなわれる必要があります。サーバは存在しているHTTP接続をよりネイティブな TCP/IP接続へと置き換えるために初期ハンドシェイク(TCP接続するのに必要な確認手続き)をおこなう必要があります。オープンソースプロジェクトのKaazing Gatewayはこれが可能なサーバの代表格で、長時間接続を数万レベルで必要とするサービスにも対応できるスケーラビリティも備えています。 Kaazing GatewayのベンダであるKaazingは最新のウェブブラウザであればどれでもWebSocketを使うことができるようになる JavaScriptライブラリも提供しています。このようにWebSocketは既に利用可能な状況にあるのです。

HTML 5 Web socketsの取り組みに関しては、KaazingがオープンソースのWebSocketサーバであるKaazing GatewayKaazing Gatewayの8.09_2 Atlantisをリリースしている。これはMozilla Public Licenseから派生したOSI公認のCommon Public Attribution License(CPAL)(リンク)の下で利用可能だ。

Kaazing Gateway提供のHTML 5 WebSocketをエミュレートするJavaScriptライブラリを使えば、ディベロッパはWebSocketの機能を使えるようになり、 WebSocketインターフェースを活用し、かつ最新のブラウザや将来のブラウザでも利用可能なアプリケーションを作ることができます。

Kaazing Gatewayのバックにある超高パフォーマンスのサーバは、ひとつで数万の同時接続に対応可能です。また複数のサーバインスタンスを従来のHTTPロードバランサやDNSラウンドロビン(1つのドメインに複数のIPアドレスを割り当てる負荷分散手法)でクラスタ化することができ、長時間のクライアント接続をどれだけでも処理できます。その上、大量の接続であっても、高パフォーマンスとStaged Event Drivenアーキテクチャ(SEDA)のおかげで高いデータスループットを実現することができます。

 Kaazing GatewayのAtlantis版では、Apache ActiveMQやRabbitMQといった主要なメッセージサービス向けのJavaScriptクライアント、そしてOpenFireや Javverd、その他の主要なチャットサーバのようなXMPPサービスのクライアントが含まれています。これによって株式指標、オンライントレーディングシステム、オンラインラインゲームといったウェブベースのチャットアプリケーションやメッセージングアプリケーションを素早く作ることが簡単にできます。

Kaazing Gateway 8.12のリリースでは、Server-side Events、高度なセキュリティサービス、XMPP (リンク)(Jabber(リンク)のプロトコル)やSTOMP(リンク)(ActiveMQ(リンク)やRabbitMQ(リンク)やOpenMQ(リンク)などでのプロトコル)の拡張サポートといったより多くのHTML 5機能の実現が計画されている。

これらのライブラリはHTML 5 Server-sent Eventsやクロス・ドキュメント・メッセージングを簡略化するHTML 5 postMessageを全ての最新ブラウザで使用可能にします。KaazingのHTML 5 ライブラリ群にはシンプルなDOMベースのストレージ技術であるHTML 5 Offline Storageも含まれます。またKaazing Gatewayとそのクライアントライブラリ群は、クライアント側でクロスサイトのリクエストを可能にするW3C Access Controls for Cross-Site Requests、一般的にはCross-site XmlHttpRequestsとして知られるメカニズムも提供するようになりました。

 HTML 5向けサポートを拡張したのに加えて、Kaazing Gateway 8.12ではグループチャットのような高度なXMPP機能も提供します。今回のリリースでは、既存のJava Message Service(JMS)サービス(JBoss Messaging、Tibco EMS、OpenMQ、SwiftMQ、WebSphere MQなど)とKaazing Gatewayを一緒に使うためのSTOMP-JMS Adapterも含まれるようになりました。

Ajax(参考記事リンク)Comet(参考記事リンク)、そしてリッチ・インターネット・アプリケーション(参考記事リンク)についてのその他の情報はリンク先のInfoQページにあるのでどうぞ。

 

原文はこちらです:http://www.infoq.com/news/2008/12/websockets-vs-comet-ajax

この記事に星をつける

おすすめ度
スタイル

BT