classes

LocalBroadcaster.as

Stiahnuť LocalBroadcaster.as

package sk.yoz.net
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.StatusEvent;
    import flash.net.LocalConnection;
    import flash.net.SharedObject;
    
    import sk.yoz.events.LocalBroadcasterEvent;
    
    public class LocalBroadcaster extends EventDispatcher
    {
        private var connection:LocalConnection;
        private var _channel:String;
        private var so:SharedObject = SharedObject.getLocal("LocalBroadcaster", "/");
        private var senderList:Object;
        
        public static const HALLO_WORLD_MESSAGE:String = ".,*-@Hallo World@-*,.";
        
        private var connectionList:Array = new Array();
        
        public function LocalBroadcaster()
        {
            super();
            var result:Boolean;
            var attempts:uint = 0;
            while(!result || attempts >= 5)
            {
                result = initConnection(randomChannel);
                attempts++;
            }
            
            if(result)
                addChannel(public::channel);
            else
                trace("LocalBroadcaster: Unable to create connection!");
        }
        
        private function get randomChannel():String
        {
            return Math.round(Math.random() * uint.MAX_VALUE).toString(36);
        }
        
        public function get channel():String
        {
            return _channel;
        }
        
        [Bindable(event="channelsChanged")]
        public function get channels():Array
        {
            var list:Array = [];
            if(!so || !so.data.hasOwnProperty("channels"))
                return list;
            for(var channel:String in so.data.channels)
                list.push(channel);
            return list;
        }
        
        private function set channel(value:String):void
        {
            _channel = value;
        }
        
        private function initConnection(channel:String):Boolean
        {
            connection = new LocalConnection();
            connection.client = this;
            try
            {
                connection.connect(channel);
            }
            catch(error:Error)
            {
                //dispatchEvent(new Error(error.message));
                connection = null;
                return false;
            }
            
            private::channel = channel;
            dispatchEvent(new LocalBroadcasterEvent(LocalBroadcasterEvent.CHANNEL_CREATED, false, false, channel));
            dispatchEvent(new Event("channelsChanged"));
            broadcast(HALLO_WORLD_MESSAGE);
            return true;
        }
        
        private function addChannel(channel:String):void
        {
            if(!so.data.channels)
                so.data.channels = {};
            if(so.data.channels.hasOwnProperty(channel))
                return;
            so.data.channels[channel] = channel;
            try
            {
                so.flush();
            }
            catch(error:Error){}
            dispatchEvent(new LocalBroadcasterEvent(LocalBroadcasterEvent.CHANNEL_ADDED, false, false, channel));
            dispatchEvent(new Event("channelsChanged"));
        }
        
        private function removeChannel(channel:String):void
        {
            if(!so.data.channels)
                return;
            delete so.data.channels[channel];
            try
            {
                so.flush();
            }
            catch(error:Error){}
            dispatchEvent(new LocalBroadcasterEvent(LocalBroadcasterEvent.CHANNEL_REMOVED, false, false, channel));
            dispatchEvent(new Event("channelsChanged"));
        }
        
        public function broadcast(data:Object, broadcastToSender:Boolean = false):void
        {
            var sender:LocalConnection;
            senderList = {};
            for(var channel:String in so.data.channels)
            {
                if(!broadcastToSender && channel == public::channel)
                    continue;
                sender = new LocalConnection();
                sender.addEventListener(StatusEvent.STATUS, onStatus);
                sender.send(channel, "receive", public::channel, data);
                senderList[channel] = sender;
                dispatchEvent(new LocalBroadcasterEvent(LocalBroadcasterEvent.CHANNEL_FOUND, false, false, channel));
                dispatchEvent(new Event("channelsChanged"));
            }
        }
        
        public function receive(channel:String, data:Object):void
        {
            if(data == HALLO_WORLD_MESSAGE)
            {
                addChannel(channel);
                dispatchEvent(new LocalBroadcasterEvent(LocalBroadcasterEvent.RECEIVED_HALLO_WORLD, false, false, channel, data));
                return;
            }
            
            dispatchEvent(new LocalBroadcasterEvent(LocalBroadcasterEvent.RECEIVED_DATA, false, false, channel, data));
        }
        
        private function onStatus(event:StatusEvent):void
        {
            if(!senderList)
                return;
                
            var sender:LocalConnection;
            var channel:String;
            for(var key:String in senderList)
                if(senderList[key] == event.target)
                    channel = key;
            
            senderList[channel] = null;
            delete senderList[channel];
            if(event.level == "error")
                removeChannel(channel);
        }
    }
}