replication sample

by andyshang
♥0 | Line 128 | Modified 2010-09-07 08:44:19 | MIT License
play

ActionScript3 source code

/**
 * Copyright andyshang ( http://wonderfl.net/user/andyshang )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/xqEY
 */

package
{
    import flash.display.Sprite;
    import flash.events.KeyboardEvent;
    import flash.events.NetStatusEvent;
    import flash.net.GroupSpecifier;
    import flash.net.NetConnection;
    import flash.net.NetGroup;
    import flash.net.NetGroupReceiveMode;
    import flash.net.NetGroupReplicationStrategy;
    import flash.text.TextField;
    import flash.ui.Keyboard;

    [SWF(width="465", height="465")]
    public class ReplicationShareSample extends Sprite
    {
        private var groupSpec:String;

        private var nc:NetConnection;
        private var group:NetGroup;
        private var objects:Array = [];

        private var statusLog:TextField;

        private var clientName:String = "g" + Math.random().toString().substr(2,5);;

        public function ReplicationShareSample()
        {
            createGroupSpec();

            nc = new NetConnection();
            nc.connect("rtmfp://stratus.rtmfp.net/564ccadb9113c58865816d86-14bc028dd6bb/");
            nc.addEventListener(NetStatusEvent.NET_STATUS, ncHandler);

            //build the UI
            var t:TextField = new TextField();
            addChild(t);
            t.width = 465;
            t.height = 28;
            t.text = clientName;
            statusLog = t;

            t = new TextField();
            addChild(t);
            t.border = true;
            t.width = 465;
            t.height = 400;
            t.y = 30;
            statusLog = t;

            t = new TextField();
            addChild(t);
            t.border = true;
            t.width = 465;
            t.height = 30;
            t.y = 434;
            t.type = "input";

            t.addEventListener(KeyboardEvent.KEY_DOWN, function(event:KeyboardEvent):void
            {
                if(event.keyCode == Keyboard.ENTER)
                {
                    shareStatus(clientName + ":" + t.text);
                    t.text = "";
                }
            });
        }

        private function ncHandler(event:NetStatusEvent):void
        {
//            log(event.info.code);
            switch(event.info.code)
            {
                case "NetStream.Connect.Closed":
//                  trace("connection closed")
                    break;
                case "NetConnection.Connect.Success":
                    joinGroup();
                    break;
                case "NetGroup.Connect.Success":
                    group.addWantObjects(0, 0xFFFFFFFF);
                    break;
                //when request failed
                case "NetGroup.Replication.Fetch.Failed":
//                  trace(event.info.index + " failed");
                    break;
                //when the object current client wants is returned.
                //notice! you will add the received object to the has-list of current
                //client, so that you add one contributing node to the group.
                case "NetGroup.Replication.Fetch.Result":
                    group.addHaveObjects(event.info.index, event.info.index);
                    receiveObject(event.info.index, event.info.object);
                    break;
                //when the object is about to send from one terminal which has it.
                case "NetGroup.Replication.Fetch.SendNotify":
//                  trace(event.info.index + " is sending");
                    break;
                //when other client request for the certain object current one has
                case "NetGroup.Replication.Request":
                    group.writeRequestedObject(event.info.requestID, retrieveObjectFromCache(event.info.index));
                    break;
            }
        }

        protected function log(text:String):void
        {
            statusLog.appendText(text + "\n");
        }

        //call this to share status
        //status will be kept in the group
        public function shareStatus(obj:Object):void
        {
            var index:int = generateUID();
            group.addHaveObjects(index, index);
            addObject(index, obj);
        }

        //TODO, replace this method with stricter one
        private function generateUID():uint
        {
            return uint(0xFFFFFF * Math.random())
        }

        private function joinGroup():void
        {
            group = new NetGroup(nc, getGroupSpec());
            group.receiveMode = NetGroupReceiveMode.NEAREST;
            group.replicationStrategy = NetGroupReplicationStrategy.LOWEST_FIRST;
            group.addEventListener(NetStatusEvent.NET_STATUS, ncHandler);
        }

        private function addObject(index:uint, obj:Object):void
        {
            log(obj.toString());
            objects[index] = obj;
        }

        private function receiveObject(index:uint, obj:Object):void
        {
            addObject(index, obj);
        }

        private function retrieveObjectFromCache(index:uint):Object
        {
            return objects[index];
        }

        private function createGroupSpec():String
        {
            var specifier:GroupSpecifier = new GroupSpecifier("mall");
            specifier.objectReplicationEnabled = true;
//            specifier.postingEnabled = true;
//            specifier.routingEnabled = true;
            specifier.multicastEnabled = true;
            //if you use stratus, comment these two lines
            //specifier.ipMulticastMemberUpdatesEnabled = true;
            //specifier.addIPMulticastAddress("225.225.0.1:50023");
            return groupSpec = specifier.groupspecWithAuthorizations();
        }

        private function getGroupSpec():String
        {
            return groupSpec;
        }
    }
}