Union Platform(8) Moduleサンプル

本エントリーではModule作成の例としてRoomModuleの作成を紹介します。UnionのバージョンはUnion alpha3を使用します。Union alpha4での動作も確認済みです。

作成するRoom Moduleの概要

ReactorからtwitというModule Messageを送信すると、Union Serverがtwitterにtwitするという機能を作ってみます。

  • Reactorから今回作成するRoom Moduleが動作するRoomへ接続する
  • RoomインスタンスのsendModuleMessage()メソッドからtwitというModule Messageを送信
  • Room Moduleは受け取ったModule Messageをtwitterに投稿する

Room Moduleの大枠の作成

com.asmple.server.union.module.roomパッケージ内にTwitModuleSampleというクラスを作成します。

package com.asmple.server.union.module.room;

import net.user1.union.core.context.ModuleContext;

public class TwitModuleSample implements Module {

    @Override
    public boolean init(ModuleContext ctx) {
        return true;
    }

    @Override
    public void shutdown() {
        // TODO Auto-generated method stub

    }

}

Module Messageのイベントをハンドリングする

Module Messageのイベントハンドリング機能を追加するしたものが下記です。

package com.asmple.server.union.module.room;

import java.util.Map;

import net.user1.union.api.Message;
import net.user1.union.api.Module;
import net.user1.union.core.context.ModuleContext;
import net.user1.union.core.event.RoomEvent;

public class TwitModuleSample implements Module {

    @Override
    public boolean init(ModuleContext ctx) {
        // Room Module Messageを受信した際のイベントを監視
        ctx.getRoom().addEventListener(RoomEvent.MODULE_MESSAGE, this, "onModuleMessage");
        return true;
    }

    /**
     * Module Message受信時に実行されるメソッド
     * @param evt
     */
    public void onModuleMessage(RoomEvent evt) {
        Message message = evt.getMessage();
        Map params = message.getArgs();

        // Module Message名を確認
        if (message.getMessageName().equals("twit")) {
            // 引数オブジェクトからtextプロパティを取得する
            String text = (String)params.get("text");
        }
    }

    @Override
    public void shutdown() {
        // TODO Auto-generated method stub

    }

}

Module Messageイベントを監視

リスナー登録はこのように行います。AS3と似た構文で記述可能です。

        ctx.getRoom().addEventListener(RoomEvent.MODULE_MESSAGE, this, "onModuleMessage");

onModuleMessageハンドラ

ハンドラ内でメッセージの名前を確認し、引数のオブジェクトを取得します。これらの値を使ってtwitterと連携すれば良さそうですね。

    public void onModuleMessage(RoomEvent evt) {
        Message message = evt.getMessage();
        Map params = message.getArgs();

        // Module Message名を確認
        if (message.getMessageName().equals("twit")) {
            // 引数オブジェクトからtextプロパティを取得する
            String text = (String)params.get("text");
        }
    }

Twitterに投稿する機能を追加する準備

twitterのアカウントをお持ちでない方は、twitterアカウントのidとpasswordを用意してください。

twitter4jの導入

Twitter4Jからtwitter4j-2.0.9.zipをダウンロードしてきます。

アーカイブを解凍したら、twitter4j-2.0.9.jarをUnion Serverをインストールしたディレクトリのlib配下へコピーします。

eclipseのライブラリパスを設定

[swfobj src="http://fla.la/wp-content/uploads/2009/09/union_platform008_001.swf?startingPlaybackMode=1" alt="ライブラリパスに.jarを追加する" align="center" width="512" height="312"]

  1. Package Explorerでunion_platform(プロジェクト名)からコンテキストメニューを表示します。
  2. Propertiesを選択します。
  3. JAVA Build PathからLibrariesタブを選択します。
  4. Add JARsボタンをクリックします。
  5. 先ほど追加したlib/twitter4j-2.0.9.jarを選択します。

startup.bat(.sh)の編集

前回のstartup.bat(.sh)に追記していきます。前回の記事をお読みでない方は、Union Platform(7) Union Server Module作成準備を参照して下さい。

Windows環境の場合はstartup.batを編集します。

java -cp libunion.jar;libstax-api-1.0.1.jar;libwstx-asl-3.2.6.jar;libcom-asmple-server-union-module.jar net.user1.union.core.UnionMain start

;libcom-asmple-server-union-module.jarの後ろに以下を追記します。

;libtwitter4j-2.0.9.jar

変更後は以下のようになります。

java -cp libunion.jar;libstax-api-1.0.1.jar;libwstx-asl-3.2.6.jar;libcom-asmple-server-union-module.jar;libtwitter4j-2.0.9.jar net.user1.union.core.UnionMain start

Mac OS X, Linux環境の場合はstartup.shを編集します。

#!/bin/sh
java -cp lib/union.jar:lib/stax-api-1.0.1.jar:lib/wstx-asl-3.2.6.jar:lib/com-asmple-server-union-module.jar net.user1.union.core.UnionMain start &

lib/com-asmple-server-union-module.jarの後ろに以下を追記します。

:lib/twitter4j-2.0.9.jar

変更後は以下のようになります。

#!/bin/sh
java -cp lib/union.jar:lib/stax-api-1.0.1.jar:lib/wstx-asl-3.2.6.jar:lib/com-asmple-server-union-module.jar:lib/twitter4j-2.0.9.jar net.user1.union.core.UnionMain start &

Twitter4Jを組み込む

実際にTwitter4Jを組み込んだものが以下のコードです。

package com.asmple.server.union.module.room;

import java.net.URLDecoder;
import java.util.Map;

import twitter4j.Status;
import twitter4j.Twitter;

import net.user1.union.api.Message;
import net.user1.union.api.Module;
import net.user1.union.core.context.ModuleContext;
import net.user1.union.core.event.RoomEvent;

public class TwitModuleSample implements Module {
    private Twitter twitter;

    // twitterのidを設定
    private static final String TWITTER_ID = "your twitter id";

    // twitterのpassowrdを設定
    private static final String TWITTER_PW = "your twitter password";

    @Override
    public boolean init(ModuleContext ctx) {
        // Room Module Messageを受信した際のイベントを監視
        ctx.getRoom().addEventListener(RoomEvent.MODULE_MESSAGE, this, "onModuleMessage");

        // twitter用インスタンスの生成
        twitter = new Twitter(TWITTER_ID, TWITTER_PW);
        return true;
    }

    /**
     * Module Message受信時に実行されるメソッド
     * @param evt
     */
    public void onModuleMessage(RoomEvent evt) {
        Message message = evt.getMessage();
        Map params = message.getArgs();

        // Module Message名を確認
        if (message.getMessageName().equals("twit")) {
            // 引数オブジェクトからtextプロパティを取得する
            String text = (String)params.get("text");
            text = URLDecoder.decode(text);

            // twitterへ書き込みをする
            try {
                Status status = twitter.update(text + " #union");
                evt.getRoom().sendMessage(
                    "response", "ok",
                    "http://twitter.com/"
                    + TWITTER_ID + "/status/" + status.getId());
            } catch (Exception e) {
                evt.getRoom().sendMessage(
                    "response", "ng", "can't twit " + TWITTER_ID);
            }
        }
    }

    @Override
    public void shutdown() {
        // TODO Auto-generated method stub

    }

}

Room Moduleをdeployする

前回と同じようにAntツールを使ってdeployします。deploy後は、stopserver.bat(.sh)、startserver.bat(.sh)を実行してUnion Serverを再起動しておきましょう。

簡単なClientを作ってみる

下記サンプルが動作するためには、localhostに先ほどのRoom Moduleを定義したUnion Serverが起動している必要があります。

twitボタンをクリックすると、先ほど設定したtwitterアカウントで入力したメッセージを呟きます。

Room Moduleの指定

2つの方法があります。

Reactorで指定する方法

Reactorで指定することで、任意のRoomに任意のRoom Moduleを割り当てることが可能となります。 具体的には以下のように、RoomModulesインスタンスを生成して、割り当てたいRoom Moduleのクラスを指定します。

            // Room モジュールを指定します。
            var modules:RoomModules = new RoomModules();
            modules.addModule(
                "com.asmple.server.union.module.room.TwitModuleSample",
                RoomModuleType.CLASS);

            // Room モジュールを指定しながらRoomを生成します。
            _room = _reactor.getRoomManager().createRoom(
                "twitRoom", null, null, modules
             );
Union Serverのunion.xmlで指定する方法

Room Moduleを割り当てたいRoomが固定の場合、Union Serverのunion.xmlで指定すると良いです。今回のRoom ModuleをtwitRoomに割り当てる場合にはunion.xmlに以下のようなセクションを追加します。この例では、twitRoomというRoom IDのRoomにcom.asmple.server.union.module.room.TwitModuleSampleというRoom Moduleが割り当てられます。

    
        
            twitRoom
            
                
                    
                        com.asmple.server.union.module.room.TwitModuleSample
                    
                
            
        
    

まとめ

今回は、Module Messageに注目してRoom Moduleを作成してみました。Server側のイベント発生のタイミングで他にも色々なModuleを作成する事が出来ます。Union ServerのModuleを作成すると、よりリッチなマルチユーザアプリケーションを作成する事が出来ます。

今後も、バージョンが更新されるたびに、Union Platformの調査を続けて行きたいと思います。これからもUnionのバージョンアップが楽しみです。

関連記事

  1. UnionPlatform (1) 概要
  2. UnionPlatform (2) 概念
  3. Union Platform(3) 情報の共有化
  4. Union Platform(4) Reactorのイベント
  5. Union Platform(5) チャットを作る
  6. Union Platform(6) Union Server入門
  7. Union Platform(7) Union Server Module作成準備
  8. Union Platform(8) Moduleサンプル