本連載では、このTech-Sketchから「コレは!」というテーマをピックアップし、加筆修正して皆様にお届けいたします。
リアルタイムWebとSocket.IO
栄えある連載第1回は、リアルタイムWebとSocket.IOについてお届けいたします。Tech-Sketchに掲載した元ネタはこちらです。
JavaScriptとDynamic HTMLによる「動的に表示内容が更新されるWebサイト」は、JavaScript内から非同期にサーバへ接続しデータを取得する技術、いわゆるAjaxが利用できるようになったことを皮切りに、爆発的に広がりました。Google Mapsなどがその代表例です。
このGoogle Mapsは、表示する場所や縮尺を変更するといった「利用者の操作」を契機として新しいデータをサーバへ取りに行く仕組みになっています。そのためサーバ側でデータが変更されたとしても、次にデータを取得するまで利用者は変更内容を知ることができません。
一方、例えばFacebookチャットのようなチャットアプリでは、参加者が書き込んだメッセージは即座にすべての参加者へ自動的に通知されます。たとえ利用者が「新しいメッセージを取得する」操作を行わなくても。
後者のような「情報の更新をリアルタイムに反映し共有する概念やその仕組み」が、"リアルタイムWeb"と呼ばれています。
この"リアルタイムWeb"を実現するためには、ブラウザとサーバ双方から任意のタイミングでデータを送受信する必要があります。このような仕組みはさまざまな方法で実現することができますが、状況によって適切に使い分ける必要があるため、一つ一つ自力で実装し使い分けるのはかなり面倒です。
そこでSocket.IOが登場します。Socket.IOはさまざまなリアルタイムWeb技術をラップし、統一されたシンプルなAPIを提供しているため、通信部分の煩雑さを意識することなく、リアルタイムWebを簡単に構築することができます。
本記事では、代表的なリアルタイムWeb技術の概観と、Socket.IOを用いた実装について解説します。
リアルタイムWeb技術の概観
リアルタイムWebを実現する技術には、HTTPプロトコルの制約内で無理やり実現するものからプラグインによるソケット通信、はたまた新しい専用プロトコルの利用まで、さまざまな実現方法があり、それぞれ特徴があります。サーバ・ネットワーク機器・ブラウザの対応状況、バイナリデータの送受信可否、クロスドメイン通信可否、レイテンシ、サーバへの負荷、等々。このようなさまざまな制約を考慮して、適切なリアルタイムWeb技術を選択しなければなりません。
ポーリングを用いる手法(HTTP PollingやJSONP Pollingなど)
1つ目はHTTPやJSONPによるポーリングです。
最もシンプルなため、プロキシやリバースプロキシ、NATが挟まった複雑なネットワーク構成であっても、またHTML5に対応した最新ブラウザでなくても動作します。AjaxによるHTTPリクエストを繰り返しているだけなので、サーバ側に特別な実装をする必要もありません。
ただしサーバ側でのイベント発生に追随するためには頻繁にポーリングしなければならず、ネットワーク帯域とサーバリソースを無駄に消費してしまいます。クライアント数の増加に対してスケールしないアーキテクチャなので、どうしてもという場合以外は使わないほうが良いでしょう。
Comet(HTTP StreamingやHTTP Long polling)
2つ目はCometです。Cometとは「クライアントから送信されてきたHTTPリクエストをサーバが維持し、サーバーからPUSHすべきイベントの発生(もしくはリクエストのタイムアウト)を契機にHTTPレスポンスを返す」というWebアプリケーション・モデルの総称で、サーバがブラウザとのHTTPコネクションを維持しているため、イベント発生時に即座にサーバからブラウザへデータをPUSHすることができます。
Cometは概念なので、Ajax multipart streamingやAjax long pollingなど、さまざまな実現方式があります。例えばAjax long pollingの場合、イベント発生時に保持していたHTTPリクエストに対してHTTPレスポンスを返すことで、リアルタイムに情報を送信することを可能としています。
このようにCometはHTTPプロトコルの枠内でリアルタイムWebを実現していますので、単純なポーリングと同様、ネットワーク経路の制約に影響されにくいのが利点です。またAjax multipart streamingはブラウザ依存がありますが、Ajax long pollingであればAjaxをサポートしているブラウザならほぼ動作すると期待できます。