cometdを用いたリアルタイム通信/サーバ・プッシュ

Webアプリケーションではサーバからのデータ配信をクライアント側でリアルタイムに受信する方法が必要となるケースがあります。従来これは画面のリロードやポーリング等による実装がなされてきました。しかし、さらなるリアルタイム性を実現するために「Comet(コメット)」と呼ばれるHTTPセッションを接続し続けて、疑似的にサーバ・プッシュ(サーバ配信)を実装する手法がAjaxとともに多く使われるようになってきました。これをCurlで実装するための方法を記載していきたいと思います。

当サンプルでは、BAYEUXプロトコル(1.0Draft1)というJSONフォーマットで定義されたプロトコルの実装であるcometdのクライアントサイドライブラリを用いて、サーバ・プッシュを実現できるようにしています。そこで、Javaの実装の一つであるJettyに搭載されているcometdを利用して、サンプルを説明していきたいと思います。ちなみにcometd/BAYEUXプロトコルの詳細については以下のサイトを参照してください。
  http://www.cometd.com/

cometd準備及びサンプル実行

1.以下のサイトからJetty6.1.7をダウンロードします。
  http://www.mortbay.org/

2.上記でダウンロードしたzipファイルを展開します。

3-1.Windowsの場合、Jettyを展開したディレクトリのbin/Jetty-Service.exeをダブルクリックし、Jettyを起動します。
3-2.UNISの場合、jetty.shによりJettyサーバを起動します。

4.サンプルpublish-stock-price.curlを実行しますと以下のような画面が表示されますので、「株価配信ボタン」を押下します。

5.別ブラウザにてsubscribe-stock-price.curlを起動し、以下の画面を表示させ、「リアルタイム株価受信開始」ボタンを押下しますと、株価をリアルタイムで受信することができます。

リアタイムアプリケーション・サンプル

これらのサンプルプログラムを元に、実装方法を説明していきます。

我々は、cometdのCurlクライアントであるCometdClientクラスを用意しています。このクラスは以下のメソッドを用意しています。(COM.CURL.MESSAGE-SERVICEパッケージを参照)←リンク

  || 初期化を行います。urlに対象のサーバを指定します。
|| ここでは、http://localhost:8080/cometdを指定しています。
  {method public {initialize url:Url}:void }

  || 購読を開始します。
  {method public {subscribe channel:String, …:EventHandler}:void }

  || 購読を終了します。
  {method public {unsubscribe channel:String}:void }

  || データを購読しているクライアントに対して送信します。
  {method public {publish channel:String, message:JsonValue}:void }

  || サーバとの接続を切断します。
  {method public {disconnect}:void }

まず、はじめにCometdClientクラスのインスタンスを生成し、initializeメソッドを実行します。これによりcometdサーバとの接続が確立されます。

    def client:Client = {CometdClient}
    {client.initialize {url cometd-server}}

次に受信する側(ここでは株価情報を受信するsubscribe-stock-price.curl)で、subscribeメソッドを用いて、配信(publishメソッド)データを受け取るための処理を開始します。その後、他のクライアントもしくはローカルからpublishメソッドが実行されますと(ここでは株価情報を配信しているpublish-stock-price.curl)、受信側ではsubscribeメソッドの引数として指定されたイベントMessageReceiveEventが発生します。publishによる送信されたデータはMessageReceiveEventのmessageゲッターで取得することができます。この値はJSONオブジェクトとなっています。また、subscribe/subscribe/unsubscribeメソッドの引数にある”channel”とは、グループのようなものです。この同一チャネル間の中のみでデータ送受信を行います。複数のチャネルに対してsubscribe/publishをすることが可能となっていますが、違うチャネル間ではデータ送受信を行うことができません。 

{client.subscribe
channel,
    {on e:MessageReceiveEvent do
        let msg:JsonValue = e.message
        || ….
     }
}

 

{client.publish
channel,
{JsonObject
“ticker”, tickers[{rand.next-in-range 0, 3}],
“price”, {rand.next-in-range -20, 20} & “”
    }
}

subscribeを中止する場合は、unsubscribeメソッドを実行します。また、コネクションを切断するためには、disconnectメソッドを実行します。

おまけ

Apache Tomcatでcometdを稼動させるには、Jettyに格納されている以下のファイルをTomcatのホームディレクトリ配下のwebappsにコピーしてください。

  cometd-bayeux-6.1.6rc1.jar
  cometd-api-0.9.20070918.jar
  jetty-util-6.1.6rc1.jar

サポートバージョン

RTE6.0以上

コードサンプルのダウンロード

cometdクライアントサンプル

comtedソースコード(Apps Galleryから)