カスタム検索

2009年4月7日火曜日

GrailsでblazeDSプッシュ配信!その1

blazeDSといえばプッシュ機能がついていますが、grailsのflex pluginでは定義されてないので使う事が出来ません。

せっかくあるんだし、サーバから一斉にメッセージ配信とかなんかカッコイイ(ここ重要)ので実装してみました。
まずは plugin を改良して streaming と polling の定義を追加します。

service-config.xml を編集します。

services の中に以下の定義を追加。

<service id="message-service" class="flex.messaging.services.MessageService">
<adapters>
<adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />
</adapters>

<default-channels>
<channel ref="grails-streaming-amf"/>
<channel ref="grails-polling-amf"/>
</default-channels>

<destination id="sb-1" />
</service>


*デフォで入っている default-channels が services 全体になっているので、はじめから定義されている remoting-service の中に正しく入れてやる

desitination ってのが接続するキーになります、このタグの中にある security って項目を使うと別のユーザ管理と認証が出来ます。
(acegi と連動出来たら素敵ですが、とりあえず認証無しで)

channelsに以下を追加

<channel-definition id="grails-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel">
<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/streamingamf" class="flex.messaging.endpoints.StreamingAMFEndpoint"/>
<properties>
<idle-timeout-minutes>0</idle-timeout-minutes>
<max-streaming-clients>10</max-streaming-clients>
<server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis>
<user-agent-settings>
<user-agent match-on="MSIE" kickstart-bytes="2048" max-streaming-connections-per-session="1"/>
<user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="1"/>
</user-agent-settings>
</properties>
</channel-definition>

<channel-definition id="grails-polling-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
<polling-enabled>true</polling-enabled>
<polling-interval-seconds>4</polling-interval-seconds>
</properties>
</channel-definition>


FlexPlugin では GrailsBootstrapService というクラスが BlazeDS の起動時に読み込まれるので、ここで MessageClientListener を登録してやります。


MessageClient.addMessageClientCreatedListener(new ClientWatcher())


ClientWatcher は MessageClientListener を implements したクラス、サンプルでこんなのを用意してみました。


package org.codehaus.groovy.grails.plugins.flex;

import flex.messaging.MessageClient;
import flex.messaging.MessageClientListener;

public class ClientWatcher implements MessageClientListener {
/**
* クライアントが接続したときに呼ばれる。
*/
public void messageClientCreated(MessageClient msgClient) {
println "connect client"

// 自身をクライアントの切断を監視するリスナとしても登録する。
msgClient.addMessageClientDestroyedListener(this);
}

/**
* クライアントが切断したときに呼ばれる。
*/
public void messageClientDestroyed(MessageClient msgClient) {
println "disconnect client"

// 明示的にセッションを破棄する。
msgClient.getFlexSession().timeout();
}
}


でもクラスを直指定はいけてないので、Acegi風にDefaultConfigで対応するクラスを乗せ変えられるようにしてみました。


// Configのロード
GroovyClassLoader classLoader = new GroovyClassLoader(getClass().getClassLoader())
ConfigObject config
ConfigObject flexConfig
try {
flexConfig=new ConfigSlurper().parse(classLoader.loadClass('FlexConfig'))
} catch(Exception e) {
}

if(flexConfig) {
config=flexConfig
} else {
config=new ConfigSlurper().parse(classLoader.loadClass('DefaultFlexConfig'))
}

// クライアントの接続を監視する
def className="${config.flex.blazeDs.messageClientListener}"
def clientListener=classLoader.loadClass(className).newInstance()
MessageClient.addMessageClientCreatedListener(clientListener)


ここをやっている時、Class.forName() でエラー出てハマっていたので Google先生に聞いてみたら自分が教えてくれた あるあるw
でも GroovyClassLoader を定義してるんでそっちを使ってみた

これで下準備は完了!
次回は接続&メッセージ送信編

この件の事もあるし、要望あれば plugin 公開してもいいかな・・・)

0 件のコメント: