Messaging中にRemoteObjectにデータを保存したり、メソッド実行したりする際にRemotingObjectにアクセスする方法を忘れないようにメモ。
- パッケージ名:packagename
- Messagingをするクラス名:MessagingAdapter(ServiceAdapterのサブクラス)
- Messagingのadapter-definition id:hoge-messaging-adapter
- RemoteObjectのクラス名:ClassName
- RemoteObjectのdestination id:hoge-remote-object
FlexContext.getServletContext()で取得したServletContextから、getAttribute('destination id')でRemoteObjectの参照を取得する。
これでメッセージングする度にRemoteObjectのsetDataにmessageのbodyが渡されるようになる。
あとは煮るなり焼くなり・・・
package packagename;
import packagename.ClassName;
import flex.messaging.config.ConfigMap;
import flex.messaging.messages.Message;
import flex.messaging.FlexContext;
import flex.messaging.MessageBroker;
import flex.messaging.services.MessageService;
import flex.messaging.services.ServiceAdapter;
import java.util.HashMap;
import javax.servlet.ServletContext;
public class MessagingAdapter extends ServiceAdapter {
private MessageBroker messageBroker;
private MessageService messageService;
private ServletContext servletContext;
private ClassName remoteObject;
@Override
public void initialize
(String id, ConfigMap properties
) {
}
@Override
public void start() {
// MessagingService取得
messageBroker = MessageBroker.getMessageBroker(null);
messageService = (MessageService) messageBroker.getService("hoge-messaging-service");
// RemoteObject取得
servletContext = FlexContext.getServletContext();
remoteObject = (IconManager) servletContext.getAttribute("hoge-remote-object");
}
@Override
public void stop() {
}
@Override
public Object invoke
(Message message
) {
// Messaging配信
messageService.pushMessageToClients(message, true);
messageService.sendPushMessageFromPeer(message, true);
// RemoteObjectへmessageのbodyを渡す
remoteObject.setData(hmMessage);
return null;
}
}
ちなみにこの時の*-config.xmlたちはこんな感じ。
<?xml version="1.0" encoding="UTF-8"?>
<service id="hoge-messaging-service"
class="flex.messaging.services.MessageService">
<adapters>
<adapter-definition id="actionscript"
class="flex.messaging.services.messaging.adapters.ActionScriptAdapter"
default="true" />
<adapter-definition id="hoge-messaging-service"
class="packagename.MessagingAdapter" />
</adapters>
<!-- ...中略... -->
</service>
<?xml version="1.0" encoding="UTF-8"?>
<service id="hoge-remoting-service" class="flex.messaging.services.RemotingService">
<!-- ...中略... -->
<destination id="hoge-remote-object">
<properties>
<source>packagename.ClassName</source>
<scope>application</scope>
</properties>
</destination>
</service>
BlazeDSのMessaging APIsのServiceAdapterとAbstractBootstrapServiceのサブクラスを作っていた時のお話。
public class MessagingAdapter extends ServiceAdapter {
// ...中略...
@Override
public Object invoke
(Message message
) {
System.
out.
println(message.
getClientId());
// Result 19FF0FC6-1818-5450-D6BE-33FF6297BFD0
}
}
public class BootstrapService extends AbstractBootstrapService {
// ...中略...
class ClientWatcher implements MessageClientListener {
public void messageClientCreated(MessageClient msgClient) {
System.
out.
println(msgClient.
getClientId());
// Result 19FF11B5-B30A-3172-EDD2-0AB30F8A73EA
}
}
}
この二つで取得できるクライアントIDって同一のクライアントなはずなのに別モノ。
この二つのクラスからRemoteObjectにクライアントID渡してごにょごにょしようとしてたらできなくて、調べていくとこういうことだった。
同じものが取得できると思ったのに。同じものが取得できると思ったのに。
BlazeDSの主要な機能の一つであるMessegingのサーバーサイドの処理について。
-
services-config.xmlにstreamingの設定を書く。
<?xml version="1.0" encoding="UTF-8"?>
<service id="message-service" class="flex.messaging.services.MessageService">
<adapters>
<adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />
<!-- <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/> -->
</adapters>
<default-channels>
<channel ref="my-streaming-amf"/>
</default-channels>
<destination id="messagingTutorial"/>
</service>
-
messaging-config.xmlにデフォルトチャンネルの設定、サービスのIDを書く。
<channel-definition id="my-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>100</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="10"/>
<user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="10"/>
<user-agent match-on="AppleWebKit" kickstart-bytes="2048" max-streaming-connections-per-session="10"/>
</user-agent-settings>
</properties>
</channel-definition>
-
サーバーを再起動。
BlazeDSの主要な機能の一つであるRemotingのサーバーサイドの処理について。
-
remoting-config.xmlで、これから使うRemotingのサービスを定義する。
<destination id="***">には、クライアントからサーバーサイドJavaのメソッドを呼び出すときのユニークなIDを入力。
<source>***</source>には、サーバーサイドJavaのパッケージ名.クラス名を入力。
<destination id="remotingTutorial">
<properties>
<source>tutorial.RemotingTutorial</source>
<scope>application</scope>
</properties>
</destination>
-
「ファイル > 新規 > プロジェクト」より、「Javaプロジェクト」を作成する。
-
「内容 > 外部ソースからプロジェクトを作成」をチェックし、\tutorial\WEB-INF\classesを指定し、「次へ」。
-
「ライブラリー > 外部JARの追加」で、\tutorial\WEB-INF\lib内の全jarファイルを指定し、クラスパスを通す。
-
tutorial-javaを右クリックして、「新規 > パッケージ」をクリック。「名前」に1.で設定したパッケージ名(このチュートリアルでは"tutorial")を入力して「終了」。
-
\tutorial\WEB-INF\srcに1.で設定したクラス名のJavaのソースファイルを作る。(このチュートリアルでは"RemotingTutorial.java)
-
6.で作ったクラスファイル(RemotingTutorial.java)を、5.で作ったパッケージ内にリンクする。tutorialを右クリックして、「新規 > ファイル」をクリック。「拡張」をクリック後、6.で作ったクラスファイルを指定し、終了。
-
RemotingTutorial.javaを開き、足し算して返すだけの関数を書く。
package tutorial;
import java.util.HashMap;
public class RemotingTutorial {
public RemotingTutorial() {
System.
out.
println("RemotingTutorial を初期化します");
}
public HashMap<String, Integer> getCalcResult(HashMap<String, Integer> mapSource) {
HashMap<String, Integer> mapBody = new HashMap<String, Integer>();
mapBody.put("result", (mapSource.get("param0") + mapSource.get("param1")));
return mapBody;
}
}