SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

CometとAjaxを利用したチャットサーバの実装

Webブラウザのみで行えるリアルタイムチャットアプリケーション


  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード ソースコード (109.3 KB)
ダウンロード Judeファイル (17.6 KB)

「Comet」は、クライアントからサーバへリクエストすることなく、サーバ側からクライアントに情報を送り届けることができる実装スタイルです。Cometを利用することで、相手からのメッセージをリアルタイムで表示させられるWebブラウザ用チャットアプリケーションを作ることができます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 『簡単なHTTPサーバの自作』第5回目の今回は、クライアントとの通信に、ブラウザ自身によるリクエスト/レスポンスに加えてAjaxとCometを利用した簡単なチャットアプリケーションを実装します。

 Webアプリケーションでチャットを実装する場合に考えなければならないのは、他の発言者のメッセージをどうやってブラウザへ反映させるかです。自分が発言する場合は、サーバへ対してメッセージが送信されます。従って応答データに現時点の発言を返せば済みます。しかし、この方法だけでは他の参加者の発言を発言時に読むことはできません。

 この問題を解決する手段は複数あります。

 次の図は最も原始的ですが、確実な『F5連打法』を図示したものです。

F5連打法
F5連打法

 F5連打法では、ユーザーは最新の発言がありそうだと感じた時に[F5]を叩きます。するとブラウザが最新の情報をサーバへ取りに行くため、もし発言が更新されていればその情報を表示できます。

 しかし、この方法は発言が更新されていない場合にも無駄なリクエストが行われるためサーバにとって負荷が高く、結果的にユーザーにとってはなかなか更新されないといった弊害を持ちます。

 次の図は、F5連打法を改善し、ブラウザ自身の機能を利用して再読み込みを行う『META Refresh法』を図示したものです。

META Refresh法
META Refresh法

 META Refresh法はHTMLのMETAタグを利用して一定時間ごとに、ブラウザにサーバの最新の情報を読ませます。この方法は、自動化されているという長所はあるものの、F5連打法の短所に加えて、更新間隔を短くすると入力がしにくくなる(場合によっては入力できない)ことや、更新間隔を長くすると反映が遅れるといった短所が加わります。

 Ajaxを利用すると、META Refresh法の短所である入力しにくさという問題は起きません。

AJaxを利用した場合
AJaxを利用した場合

 しかし、Ajaxを利用してもサーバへの無駄な読み取り要求は解消しません。また、更新間隔を長くとると反映が遅れるという問題点は残ったままです。

 Cometは、Ajaxが利用するのと同じXmlHttpRequest(XHRと略されることもあります)オブジェクトを利用しますが、Webサーバ側でデータが更新されるまで応答を返さないという違いがあります。このため、無駄な読み込みを抑えられると同時に、即座に更新を反映できます。

Cometを利用した場合
Cometを利用した場合

 本記事では、前回作成した非ブロックIOを利用したWebサーバの実装にComet用の実装とチャットアプリケーションを追加して、実際のCometの動作を確認できるようにします。

 なお、Cometの実装方法には、クライアント側がデータ取得のつど再接続する「ロングポーリング」と呼ばれる方法と、同一コネクション上でデータを分割して送る「マルチパートXmlHttpRequest」と呼ばれる方法がありますが、ここでは複数のブラウザで動作可能なロングポーリングを利用します。

対象読者

 本記事は、Javaプログラミングの中級者以上を対象に、Cometという比較的新しいWeb技術を解説することを目的とします。Javaのプログラム自体は前回の記事「NIOの非ブロック接続を利用した多重IOの実装」で示したものに多少手を加えただけなので、解説は省略します。

 ただしCometを実装するにはサーバ側だけではなく、クライアント側についてもAjaxを利用するためのJavaScriptプログラミングが必要です。しかも通信に利用するXmlHttpRequestはブラウザによって利用方法が異なります。またすべての処理をJavaScriptで記述するとコードが煩雑になってしまいます。

 そのため、ここではクライアント側の記述に「prototype.js」というAjax用JavaScriptライブラリ(MITライセンス)を利用します。

 従って、本記事では「prototype.js」を利用したAjaxの利用方法については簡単に解説します。

必要な環境

 本記事のソースをビルド/実行するには、J2SE 5.0以上を利用してください。ソースファイルアーカイブは、直接NetBeans 5.0のプロジェクトとして開けるように構成してあります。ただし、NetBeans 5.0を利用しなくても、直接コマンドラインからJDKおよびAntを利用してビルドすることもできます。また、チャットアプリケーションを実行するには、「prototype.js」が必要です。本記事の作成に利用した「prototype.js」のバージョンは1.5です。

 なお、ソースファイルアーカイブには、あらかじめJ2SE 5.0でビルドしたクラスファイルとjar、および「prototype.js」を含めています。そのため、JREがあればチャットアプリケーションを試すことができます。

 参考までに筆者が利用した本記事のテスト環境は以下のものです。

OSJ2SEAntIDEブラウザ
Windows XP1.5.0_091.6.5NetBeans5.0JFirefox 2.0/IE6SP2
OS X---Safari 2.0.4

コマンドラインからの実行について

 NetBeansを利用せずにコマンドラインから実行するには、JavaとAntを実行できるようにPATHを設定し、アーカイブを展開したディレクトリの中(「build.xml」が存在するディレクトリ)で

ant run

 を実行してください。これによりポート8801でチャットアプリケーションがサービスを開始します。

 チャットアプリケーションのURLは、「http://localhost:8801/html/chat.html」です。他のマシンからアクセスする場合には、localhostの箇所を実行しているマシンのものに変えてください。また、パーソナルファイアウォールなどでポート8801を塞いでいる場合には事前に開放しておく必要があります。

 終了するには、コマンドラインでブレイクさせるか(Windowsであれば[Ctrl]+[C]を押す)または、ブラウザから「http://localhost:8801/quit」にアクセスしてください。

注意事項

 各ブラウザがHTTP 1.1で稼働する同一ホストに対して同時に呼び出せるXmlHttpRequestの数には、2個という制限があります。この「2」という数字はRFC2616で無条件準拠の要件として規定されたものです。このため、例えばIEを利用している場合であれば、[ファイル]-[新しいウィンドウ]を実行すると、2つのウィンドウがXmlHttpRequestの利用待ちでデッドロックします(他のブラウザから発言することでポーリングを完了させて一時的にロックを解除できます)。これを避けるには、複数のプロセスで実行したり、異なるブラウザを利用したり、別のマシンから呼び出したりしてください。

FirefoxとIEでテスト中(他のマシンからSafariでもアクセス)
FirefoxとIEでテスト中(他のマシンからSafariでもアクセス)

 また、本実装は一応動作しますが完成したアプリケーションではありません。このため、リロードしてもロングポーリングしているXmlHttpRequestはポーリングを継続したままとなり、「新しいウィンドウ」を作ったのと同じ状態となります(ただしこの状態は一定時間経過後に元のリクエストが廃棄されて解消します)。ページのリロードが必要な場合には、リロード後に他のブラウザから発言してポーリングを完了させるか、またはブラウザを再起動してください。

NetBeans 5.0からの利用

 メニューから[ファイル]-[プロジェクトを開く]を順に選択し、ソースファイルアーカイブを展開したディレクトリの「httpserver」ディレクトリを選択して、[プロジェクトフォルダを開く]をクリックしてください。

次のページ
ファイル構成

修正履歴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

arton(アートン)

専門は業界特化型のミドルウェアやフレームワークとそれを利用するアプリケーションの開発。需要に応じてメインフレームクラスから携帯端末までダウンサイジングしたりアップサイジングしたりしながらオブジェクトを連携させていくという変化に富んだ開発者人生を歩んでいる。著書に『Ruby③ オブジェクト指向とはじめての設計...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/733 2006/12/11 12:52

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング