CodeZine(コードジン)

特集ページ一覧

AjaxとCometを利用したLiftのアプリケーションを作る

Scala+Liftによる実践Webアプリケーション開発(5)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/03/15 14:00
目次

ブラウザとCometで接続するCometTwit Snippet

 次に、ブラウザとCometで接続するCometTwit Snippetを作成します。LiftでCometを利用するSnippetは、プロジェクトで指定したパッケージ以下の「comet」パッケージ内に作成する必要があるので注意が必要です。

 プロジェクトディレクトリ以下の 「src/main/scala/demo/twitterclone/comet/」ディレクトリに、「CometTwit.scala」というファイル名で新しいファイルを、以下のリスト5の通りに作成します。

[リスト5]CometTwit.scala
package demo.twitterclone.comet

import _root_.scala.actors._
import _root_.scala.actors.Actor._
import _root_.scala.xml.{NodeSeq, Text }
import _root_.net.liftweb.http._
import _root_.net.liftweb.http.S._
import _root_.net.liftweb.http.SHtml._
import _root_.net.liftweb.util.Helpers._
import _root_.net.liftweb.util.{Box, Full}
import _root_.net.liftweb.http.js.JsCmds._
import _root_.net.liftweb.http.js.JE._
import _root_.net.liftweb.http.js.jquery.JqJsCmds._
import _root_.demo.twitterclone.model._

/**
 * ブラウザとComet接続し、非同期にメッセージを
 * 表示させるSnippet。
 * CometActorを継承し、他のListenerManagerを継承した
 * Actorに登録するため、CometListeneeトレイトを継承する。
 */
class CometTwit extends CometActor with CometListenee { // *1

  // このSnippetのNameSpace
  override def defaultPrefix = Full("twit")
  // 非同期にメッセージを表示させるタグのID
  private lazy val spanId = uniqueId + "_messages_span"

  // SinpetがTemplateから呼び出された時、
  // <Twit:messages/>タグの内容を出力する
  def render = bind("messages" -> // *2
    <span id={spanId}><div></div></span>)

  // このActorを他のActorに登録する。
  // ここでは、TwitServer Actorに登録
  protected def registerWith = TwitServer // *3

  // このActorがメッセージを受け取った時の処理
  override def highPriority = { // *4

    // caseクラス Messagesを受け取る
    case Messages(msgs) =>
      // partialUpdate関数にをPrependHtmlオブジェクト渡すことで、
      // htmlを部分的に書き換えるJavaScrpitが生成される
      partialUpdate( PrependHtml(spanId, // *5
        <xml:Group>
          { msgs.map( m =>
            <ul class="status">
              <li class="message">{ m.status.is }</li>
              <li class="user">{ userName( m.user.obj )}</li>
              <li class="dateOf">{ m.dateOf.is.toString }</li>
              <hr/>
            </ul> )
          }
        </xml:Group>
      ))
  }

  /**
   * Userモデルオブジェクトからユーザー名を取得するユーティリティ関数
   */
  def userName( user:Box[User] ) = user.dmap( "Guest" ){ user =>
    user.shortName
  }
}

 このCometTwit Snippetは、CometActorを継承し、CometListeneeトレイトを継承します。CometListeneeトレイトを継承しておくことで、他のListenerManagerを継承したActorに登録できるようになります。このCometTwitは、投稿されたメッセージを受信するために、先ほど作成したTwitServer Actorに登録する必要があるからです。

 *2のreder関数は、このSnippetがテンプレートから呼び出された際に、表示するHTMLを生成するためのものです。Cometでメッセージを表示するため、初期表示では空の<span>タグを出力しているだけです。ただし、ここで出力している<span>タグは、spanIdフィールドで定義されたIDを、タグのIDにしています。このようにすることで、メッセージ受信時の処理でspanIDのタグに対して追加でメッセージを表示させることができるようになります。

 *3のregisterWith関数では、このActorを他のActorに登録しています。先ほども述べた用に、TwitServerに登録する必要があるため、このように記述しています。実際の登録処理は継承しているCometListeneeトレイトが行います。

 *4のhighPriority関数は、メッセージ受信時の処理です。関数の書き方は、先ほどのTwitServerクラスのhighPriority関数と同じ形式です。

 このCometActorでは、メッセージとしてはcaseクラスMessagesを受信します。TwitServerに登録することで、TwitServerでupdateListeners()関数を呼び出されると、このActorにMessageモデルを内容として持つcaseクラスMessagesが送信され、最終的にこの関数が呼び出されます(この呼び出しは非同期です)。

 では、メッセージ受信時の処理について解説します(*5)。

 partialUpdate関数(CometActorトレイトがもつ関数)を呼び出すことで、指定したIDのタグの内容を部分的に書き換えることができます。

 引数は、書き換える内容を渡します。直接HTMLを返してもよいのですが、ここでは<span>タグの先頭にメッセージを次々と追加していくために、PrependHtmlオブジェクトを渡しています。

 PrependHtmlオブジェクトの第1引数には、書き換え対象のタグのIDを渡します。ここでは、表示の時に生成しておいた<span>タグのID(spanIDフィールドで定義)を渡します。

 第2引数は、追加するHTMLです。受信したcaseクラスMessagesから、登録されたMessageモデルオブジェクトを取り出して、表示する内容を生成しています。

 PrependHtmlオブジェクトは、Ajaxの例のところで説明したSetHtmlオブジェクトと同じく、JavaScriptを生成します。このように、partialUpdate関数にPrependHtmlオブジェクトのようなJavaScriptを生成するオブジェクトを渡すと、CometによりブラウザにJavaScriptが送信されて実行されます。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:Scala+Liftによる実践Webアプリケーション開発

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 尾崎 智仁(オザキ トモヒト)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5