双方向通信を実現する代表的な技術

2011年3月1日(火)
高尾 哲朗(監修:山田祥寛)

それぞれの技術の特徴

例えば会社で社員の在席状況を確認できるWebページを作って欲しいという要求があったことを想定してみてください。以下のような流れで実装を始めるのではないでしょうか?

  1. 各社員の在席/離席の状態を各社員のPCからサーバーに通知し、その情報を社員間で共有できるアプリケーションを作る
  2. サーバーに保持されたそれらの情報を確認するため、定期的にサーバーにリクエストを投げるWebページを作成する
  3. それを実現する技術を検討して、最も良いと思われる技術で実装する。

この従来のWebシステムの仕組みに対し、双方向通信を念頭に置いた設計では、各社員の在席状況が変わったら、サーバーからその状況を通知してくれるようなWebページを設計します。従来の方式と合わせて設計の選択肢が増えると、それを実現する技術の選択肢も増えますので、実装の自由度が上がります。ソリューションに合致した技術を選択するためにも、まずはそれぞれの技術の特徴や共通点などを見てみましょう。

双方向通信を実現するポイントは、サーバーからのメッセージ配信です。サーバーからメッセージ交換するためのリソースコストについては、従来のWebシステム以上に考慮した設計が必要となります。また、双方向通信を行うリアルタイムWebは、いずれの方式であってもシステムのスケールを十分に考慮した設計が必要となり、不特定多数のアクセスが生じる環境には向かないと考えます。不特定多数のアクセスが生じる、インターネット上のアプリケーションのスケーラビリティやパフォーマンスに関しては、リアルタイムWebがアプリケーション側で何とかするのでなく、HA・HPクラスタリング等での考慮が現実的でしょう。

ここでは、1つのクラスタまたは社内利用といった限定的アクセス環境におけるリアルタイムWebを前提として、これらのまとめを一覧します。

  WCF + Silverlight HTML5 + WebSockets Ajax + Comet
本稿で紹介する双方向通信技術の特徴
通信数(1リクエストにつき) 2 1 2(初期表示のみ3)
接続状態 1本切断 1本張りっ放し 1本張りっ放し
  1本切断   1本切断
通信データ WCFが扱えるすべてのデータ 文字列のみ(サーバーによって拡張可能) 文字列、JSON等、サーバーのComet実装状態に依存
サーバーからのメッセージ交換の実現方法 WCFサービスを使ったエンドポイント共有(PollingDuplexHttpBinding)によって、クライアント、サーバー双方からメッセージ交換を開始する。 標準に近いプロトコル拡張WebSocketsプロトコルを使って、コネクションの維持とサーバー、クライアント双方からのメッセージ交換の開始を行う。 シンプルなクライアント側の仕掛けとプロトコル拡張無しで双方向通信を実現するため、クライアントがレスポンスを受けたら次のリクエストをクライアントから投げることで、サーバーからのメッセージ交換開始を待つ。
リソースコスト サーバー側で保持しているのはクライアントのエンドポイントのインスタンスのコレクションなのでコストが小さい サーバー側ではクライアントからのHttpServletRequestおよびHttpServletResponseのペアにWebSocketが提供するイベントをハンドルしたインスタンスをコレクションで持つ。(jettyの場合) これらのインスタンスとネットワークリンクを保持しているため、比較的コストはかかる。※ サーバー側ではクライアントからのHttpServletRequestおよびHttpServletResponseのペアのインスタンスをコレクションで持つ(jettyの場合)。これをタイムアウトで制御するためのタイマーが生成される。これらとネットワークリンクの消滅で再度コネクション確立を試みる必要があるため、比較的コストはかかる。※
コネクション設計上の注意 クライアント、サーバー間に存在するプロキシによるコネクション切断を考える必要が無いため、長時間のコネクション放置は問題ないが、エンドポイントのインタラクティビティ継続時間の設計やサーバーポーリングタイムアウトの設計は、システムのスケールと密接にかかわる。 クライアント、サーバー間に存在するプロキシによるコネクション切断はWebSocketプロトコルによりサーバー、クライアント双方でイベントドリブン可能。ただし、コネクションは明示的に閉じる必要があるため、ソリューションによってはクライアントにそれなりの仕掛けを作成する必要がある。そのため、他と同じくシステムのスケールと密接にかかわる設計になる。 クライアント、サーバー間に存在するプロキシによるコネクション切断の可能性を考慮し、サーバー側でリクエストを待たせる時間を綿密に設計する必要がある。 短いとAjaxによる定期的なポーリングと変わらず、長いとコンテンツのリアルタイム性を失う危険性もある。 これは、システムのスケールと密接にかかわる。
※WebSocketsもCometも、各Webサーバーによって、複数コネクションを共有する等のチューニングやWebサーバー自体の軽量化が行われている。
著者
高尾 哲朗(監修:山田祥寛)
WINGSプロジェクト

有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表:山田祥寛)。おもな活動は、Web開発分野の書籍/雑誌/Web記事の執筆。ほかに海外記事の翻訳、講演なども幅広く手がける。2011年3月時点での登録メンバは36名で、現在もプロジェクトメンバーを募集中。執筆に興味のある方は、どしどしご応募頂きたい。著書多数。
http://www.wings.msn.to/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています