UnionPlatform (1) 概要

wonderflcheckmate第二回でも登場しましたUnion Platformに注目しています。 Unionは、Flashでマルチユーザアプリケーションを作成するためのプラットフォームです。2009年8月27日現在のバージョンはalpha3です。

サーバはUnion Serverと呼び、クライアントSDKをUnion Client SDKと呼びます。ドキュメントを読むとReactorという言葉を目にします。ReactorはSDKに含まれる中心的なクラスのことです。当ブログではUnionクライアントのことをReactorと呼びます。

サーバとクライアント間の通信は、FlashのSocket通信で行われ、独自のUPCプロトコルを使用します。サーバーとクライアント、その間の通信プロトコルを図にしたのが以下です。

[caption id="attachment_260" align="aligncenter" width="596" caption="Union ServerとReactorとの間の通信はUPCで行う"]Union ServerとReactorとの間の通信はUPCで行う[/caption]

図に示した通り、Union ServerはJAVA言語で書かれています。サーバー側の機能追加もJAVAを用いて行って行きます。

Union Platformの使い方

Reactor、Union Serverの各リファレンスを紹介します。ReactorのASDocはKenoさんが日本語訳を公開してくれていますので紹介させて頂きます。

connectとjoinとobserve

Union ServerにはRoomという概念があります。これはチャットの部屋と考えると分かりやすいです。Union Serverに接続(connect)しただけの状態では未だ部屋には入室していない状態です。Roomに対して、joinやobserveすることでRoomに参加出来ます。

joinは部屋に入室することを表し、observeは部屋に入室はせずに監視やROMを行うようなときに使用します。次回のエントリー以降で詳しく確認します。

[caption id="attachment_266" align="aligncenter" width="638" caption="ServerへのconnectとRoomへのjoin, observe"]ServerへのconnectとRoomへのjoin, observe[/caption]

message

クライアントは、idで識別出来るmessageを送信し、クライアント間で情報を共有する事が出来ます。サーバに送信した配達物をサーバが各クライアントへ届けるようなイメージです。詳しくは次回のエントリー以降に確認していきます。

[caption id="attachment_279" align="aligncenter" width="638" caption="messageが共有される様子"]messageが共有される様子[/caption]

サンプル

ひとまず、サーバ側はお試し用に使用できる tryunion.comを使用します。

swcファイルはDownload Union 1.0 Alpha 3ページのDownload Reactor 1.0 Alpha 3 (ActionScript 3.0 Client SDK)というリンクからダウンロード出来ます。

では、以下のswfをクリックしてみましょう。良く分からない場合は、このページを別のウィンドウやタブで開いて双方のウィンドウを確認しながらクリックしてみて下さい。 [swfobj src="http://fla.la/swf/tryunion001.swf" width="465" height="465"]

今回の例では、

  • Union Serverのホストがtryunion.com
  • Roomの名前がla.fla.tryunion1

となります。

sharedというidで識別するmessageを通じてマウスでクリックした場所をクライアント間で共有します。

ではソースをご確認下さい。

ソース

解説はコメントで記述してあります。

package
{
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import net.user1.reactor.IClient;
    import net.user1.reactor.Reactor;
    import net.user1.reactor.ReactorEvent;
    import net.user1.reactor.Room;
    import net.user1.reactor.RoomEvent;

    /**
     * ...
     * @author naoto koshikawa
     */
    public class TryUnion1 extends Sprite
    {
        //----------------------------------------------------------------------
        //  properties
        //----------------------------------------------------------------------
        //------------------------------
        //  private properties
        //------------------------------
        /**
         *
         */
        private var _reactor:Reactor;

        /**
         *
         */
        private var _room:Room;

        //----------------------------------------------------------------------
        //  methods
        //----------------------------------------------------------------------
        //------------------------------
        //  public methods
        //------------------------------
        /**
         *
         */
        public function TryUnion1()
        {
            connect();
        }

        //------------------------------
        //  private methods
        //------------------------------
        /**
         *
         */
        private function connect():void
        {
            // Union Client SDKのReactorクラスをインスタンス化します
            _reactor = new Reactor();

            _reactor.addEventListener(
                ReactorEvent.READY, _reactor_readyHandler);
            // Union Serverへ接続します。
            _reactor.connect("tryunion.com", 9100);
        }

        /**
         * サーバのRoomヘ入室します
         */
        private function join():void
        {
            // la.fla.tryunion1というRoomを作成します。
            // すでに他のクライアントが同名の部屋を作成していた場合
            // はその部屋のインスタンスを取得し
            // まだ存在していない場合は作成します。
            _room = _reactor.getRoomManager().createRoom("la.fla.tryunion1");

            // Room入室時のイベントを待機します
            _room.addEventListener(RoomEvent.JOIN, _room_joinHandler);

            // shared という名前でメッセージを送信した場合のイベントを待機します
            _room.addMessageListener("shared", _room_sharedHandler);

            // Roomへ入室します
            _room.join();
        }

        /**
         * マウスのハンドラを設定します
         */
        private function activate():void
        {
            stage.addEventListener(
                MouseEvent.CLICK, stage_mouseClickHandler
            );
        }

        //----------------------------------------------------------------------
        //  event handler
        //----------------------------------------------------------------------
        /**
         * Reactorインスタンスのconnectメソッド実行後、
         * UnionServerへ接続した際に実行されるハンドラ
         * @param   event
         */
        private function _reactor_readyHandler(event:ReactorEvent):void
        {
            join();
        }

        /**
         * Roomインスタンスのjoinメソッド実行後、
         * UnionServerのRoomへ接続した際に実行されるハンドラ
         * @param   event
         */
        private function _room_joinHandler(event:RoomEvent):void
        {
            activate();
        }

        /**
         * sharedという名前で送信したメッセージをUnion Server経由で受け取った際
         * に実行されるハンドラ
         * @param   fromClient  メッセージを送信したクライアントオブジェクト
         * @param   color   メッセージ送信時に第一引数に指定した値
         * @param   sharedX メッセージ送信時に第二引数に指定した値
         * @param   sharedY メッセージ送信時に第三引数に指定した値
         */
        private function _room_sharedHandler(
                fromClient:IClient, color:uint,
                sharedX:Number, sharedY:Number):void
        {
            graphics.beginFill(color);
            graphics.drawCircle(sharedX, sharedY, 10);

            var textField:TextField = new TextField();
            textField.autoSize = TextFieldAutoSize.LEFT;
            textField.text = fromClient.getClientID();
            textField.x = sharedX;
            textField.y = sharedY;
            textField.mouseEnabled = false;
            addChild(textField);
        }

        /**
         * stage上でクリックした際に実行されるハンドラ
         * @param   event
         */
        private function stage_mouseClickHandler(event:MouseEvent):void
        {
            // Roomに色とマウスのx座標、y座標を引数とした shared という名の
            // メッセージを送信します
            _room.sendMessage(
                "shared", true, null,
                0x777777 + 0x888888 * Math.random(),
                event.stageX, event.stageY
            );
        }
    }
}

まとめ

今回は簡単なサンプルを見てきました。次回以降UnionPlatformで何が出来るのかを詳しくみていこうと思います。

関連記事

  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サンプル