[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/support/aphlict/client/src/ -> AphlictClient.as (source)

   1  package {
   2  
   3    import flash.events.TimerEvent;
   4    import flash.external.ExternalInterface;
   5    import flash.utils.Dictionary;
   6    import flash.utils.Timer;
   7    import flash.events.UncaughtErrorEvent;
   8  
   9    final public class AphlictClient extends Aphlict {
  10  
  11      /**
  12       * The connection name for this client. This will be used for the
  13       * @{class:LocalConnection} object.
  14       */
  15      private var client:String;
  16  
  17      /**
  18       * The expiry timestamp for the @{class:AphlictMaster}. If this time is
  19       * elapsed then the master will be assumed to be dead and another
  20       * @{class:AphlictClient} will create a master.
  21       */
  22      private var expiry:Number = 0;
  23  
  24      /**
  25       * The interval at which to ping the @{class:AphlictMaster}.
  26       */
  27      public static const INTERVAL:Number = 3000;
  28  
  29      private var master:AphlictMaster;
  30      private var timer:Timer;
  31  
  32      private var remoteServer:String;
  33      private var remotePort:Number;
  34      private var subscriptions:Array;
  35  
  36  
  37      public function AphlictClient() {
  38        super();
  39  
  40        loaderInfo.uncaughtErrorEvents.addEventListener(
  41          UncaughtErrorEvent.UNCAUGHT_ERROR,
  42          this.uncaughtErrorHandler);
  43  
  44        ExternalInterface.marshallExceptions = true;
  45        ExternalInterface.addCallback('connect', this.externalConnect);
  46  
  47        this.setStatus('ready');
  48      }
  49  
  50      private function uncaughtErrorHandler(event:UncaughtErrorEvent):void {
  51        this.error(event.error.toString());
  52      }
  53  
  54      public function externalConnect(
  55        server:String,
  56        port:Number,
  57        subscriptions:Array):void {
  58  
  59        this.remoteServer  = server;
  60        this.remotePort    = port;
  61        this.subscriptions = subscriptions;
  62  
  63        this.client = AphlictClient.generateClientId();
  64        this.recv.connect(this.client);
  65  
  66        this.timer = new Timer(AphlictClient.INTERVAL);
  67        this.timer.addEventListener(TimerEvent.TIMER, this.keepalive);
  68  
  69        this.connectToMaster();
  70      }
  71  
  72      /**
  73       * Generate a unique identifier that will be used to communicate with the
  74       * @{class:AphlictMaster}.
  75       */
  76      private static function generateClientId():String {
  77        return 'aphlict_client_' + Math.round(Math.random() * 100000);
  78      }
  79  
  80      /**
  81       * Create a new connection to the @{class:AphlictMaster}.
  82       *
  83       * If there is no current @{class:AphlictMaster} instance, then a new master
  84       * will be created.
  85       */
  86      private function connectToMaster():void {
  87        this.timer.stop();
  88  
  89        // Try to become the master.
  90        try {
  91          this.log('Attempting to become the master...');
  92          this.master = new AphlictMaster(this.remoteServer, this.remotePort);
  93          this.log('I am the master.');
  94        } catch (err:ArgumentError) {
  95          this.log('Cannot become the master... probably one already exists');
  96        } catch (err:Error) {
  97          this.error(err);
  98        }
  99  
 100        this.registerWithMaster();
 101        this.timer.start();
 102      }
 103  
 104      /**
 105       * Register our client ID with the @{class:AphlictMaster} and send our
 106       * subscriptions.
 107       */
 108      private function registerWithMaster():void {
 109        this.send.send('aphlict_master', 'register', this.client);
 110        this.expiry = new Date().getTime() + (5 * AphlictClient.INTERVAL);
 111        this.log('Registered client ' + this.client);
 112  
 113        // Send subscriptions to master.
 114        this.log('Sending subscriptions to master.');
 115        this.send.send(
 116          'aphlict_master',
 117          'subscribe',
 118          this.client,
 119          this.subscriptions);
 120      }
 121  
 122      /**
 123       * Send a keepalive signal to the @{class:AphlictMaster}.
 124       *
 125       * If the connection to the master has expired (because the master has not
 126       * sent a heartbeat signal), then a new connection to master will be
 127       * created.
 128       */
 129      private function keepalive(event:TimerEvent):void {
 130        if (new Date().getTime() > this.expiry) {
 131          this.connectToMaster();
 132        }
 133  
 134        this.send.send('aphlict_master', 'ping', this.client);
 135      }
 136  
 137      /**
 138       * This function is used to receive the heartbeat signal from the
 139       * @{class:AphlictMaster}.
 140       */
 141      public function pong():void {
 142        this.expiry = new Date().getTime() + (2 * AphlictClient.INTERVAL);
 143      }
 144  
 145      /**
 146       * Receive a message from the Aphlict Server, via the
 147       * @{class:AphlictMaster}.
 148       */
 149      public function receiveMessage(msg:Object):void {
 150        this.log('Received message.');
 151        this.externalInvoke('receive', msg);
 152      }
 153  
 154      public function setStatus(status:String, code:String = null):void {
 155        this.externalInvoke('status', {type: status, code: code});
 156      }
 157  
 158    }
 159  
 160  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1