Documentation

You are viewing the documentation for the 2.1.5 release in the 2.1.x series of releases. The latest stable release series is 2.4.x.

§Comet ソケット

§Comet ソケットを作成するためにチャンクレスポンスを利用する

チャンクレスポンス を応用すると、Comet ソケットを作成することができます。 Comet ソケットは、 <script> のみを含むチャンク分割された単なる text/html レスポンスです。それぞれのチャンクに、 web ブラウザによって実行される JavaScript を含んだ <script> タグを書き込みます。これを利用することで、サーバから web ブラウザへ、イベントをリアルタイムに送信することができます: それぞれのメッセージ毎に、JavaScript のコールバック関数を呼び出す <script> タグでイベントをラップして、それをチャンクレスポンスに書き込みます。

それでは、これを確かめるデモを作成してみましょう。まず、ブラウザの console.log 関数を呼び出す <script> タグを生成するような Enumerator を作成します。

public static Result index() {
  // Prepare a chunked text stream
  Chunks<String> chunks = new StringChunks() {

    // Called when the stream is ready
    public void onReady(Chunks.Out<String> out) {
      out.write("<script>console.log('kiki')</script>");
      out.write("<script>console.log('foo')</script>");
      out.write("<script>console.log('bar')</script>");
      out.close();
    }

  };

  response().setContentType("text/html");
  return ok(chunks);
}

このアクションを web ブラウザから実行すると、ブラウザのコンソールに3つのイベントログが出力されるでしょう。

§play.libs.Comet ヘルパーを使う

チャンク分割された comet ストリームを扱うために、上で書いた内容とほぼ同じことを行う Comet ヘルパーを用意しています。

ノート: 実際のところ Comet ヘルパは、ブラウザの互換性のため最初に空のバッファデータを送信したり、メッセージとして String と JSON の両方をサポートするなど、上で書いた内容以上のことを行います。

これを使って前述の例を書き直してみましょう:

public static Result index() {
  Comet comet = new Comet("console.log") {
    public void onConnected() {
      sendMessage("kiki");
      sendMessage("foo");
      sendMessage("bar");
      close();
    }
  };
  
  return ok(comet);
}

§Forever iframe テクニック

Comet ソケットを書く標準的なテクニックとして、 iframe 内でチャンク分割された Comet レスポンスを無限にロードし、親フレームを呼び出すコールバック関数を特定するというものがあります:

public static Result index() {
  Comet comet = new Comet("parent.cometMessage") {
    public void onConnected() {
      sendMessage("kiki");
      sendMessage("foo");
      sendMessage("bar");
      close();
    }
  };
  
  return ok(comet);
}

これを、次のような HTML ページと共に使用します:

<script type="text/javascript">
  var cometMessage = function(event) {
    console.log('Received event: ' + event)
  }
</script>

<iframe src="/comet"></iframe>

次ページ: WebSocket