mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-22 13:30:55 +01:00
aa534c69f0
Summary: Currently, the `AphlictClient` will only send its subscriptions to the `AphlictMaster` once. If the original `AphlictMaster` is closed and a new master is created, then client subscriptions will be lost. Test Plan: Opened two separate tabs. Closed the "master" tab and noticed that the subscriptions were re-sent to the server. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, Korvin Differential Revision: https://secure.phabricator.com/D9487
152 lines
4.1 KiB
ActionScript
152 lines
4.1 KiB
ActionScript
package {
|
|
|
|
import flash.events.TimerEvent;
|
|
import flash.external.ExternalInterface;
|
|
import flash.utils.Dictionary;
|
|
import flash.utils.Timer;
|
|
|
|
|
|
final public class AphlictClient extends Aphlict {
|
|
|
|
/**
|
|
* The connection name for this client. This will be used for the
|
|
* @{class:LocalConnection} object.
|
|
*/
|
|
private var client:String;
|
|
|
|
/**
|
|
* The expiry timestamp for the @{class:AphlictMaster}. If this time is
|
|
* elapsed then the master will be assumed to be dead and another
|
|
* @{class:AphlictClient} will create a master.
|
|
*/
|
|
private var expiry:Number = 0;
|
|
|
|
/**
|
|
* The interval at which to ping the @{class:AphlictMaster}.
|
|
*/
|
|
public static const INTERVAL:Number = 3000;
|
|
|
|
private var master:AphlictMaster;
|
|
private var timer:Timer;
|
|
|
|
private var remoteServer:String;
|
|
private var remotePort:Number;
|
|
private var subscriptions:Array;
|
|
|
|
|
|
public function AphlictClient() {
|
|
super();
|
|
|
|
ExternalInterface.addCallback('connect', this.externalConnect);
|
|
ExternalInterface.call(
|
|
'JX.Stratcom.invoke',
|
|
'aphlict-component-ready',
|
|
null,
|
|
{});
|
|
}
|
|
|
|
public function externalConnect(
|
|
server:String,
|
|
port:Number,
|
|
subscriptions:Array):void {
|
|
|
|
this.externalInvoke('connect');
|
|
|
|
this.remoteServer = server;
|
|
this.remotePort = port;
|
|
this.subscriptions = subscriptions;
|
|
|
|
this.client = AphlictClient.generateClientId();
|
|
this.recv.connect(this.client);
|
|
|
|
this.timer = new Timer(AphlictClient.INTERVAL);
|
|
this.timer.addEventListener(TimerEvent.TIMER, this.keepalive);
|
|
|
|
this.connectToMaster();
|
|
}
|
|
|
|
/**
|
|
* Generate a unique identifier that will be used to communicate with the
|
|
* @{class:AphlictMaster}.
|
|
*/
|
|
private static function generateClientId():String {
|
|
return 'aphlict_client_' + Math.round(Math.random() * 100000);
|
|
}
|
|
|
|
/**
|
|
* Create a new connection to the @{class:AphlictMaster}.
|
|
*
|
|
* If there is no current @{class:AphlictMaster} instance, then a new master
|
|
* will be created.
|
|
*/
|
|
private function connectToMaster():void {
|
|
this.timer.stop();
|
|
|
|
// Try to become the master.
|
|
try {
|
|
this.log('Attempting to become the master...');
|
|
this.master = new AphlictMaster(this.remoteServer, this.remotePort);
|
|
this.log('I am the master.');
|
|
} catch (err:ArgumentError) {
|
|
this.log('Cannot become the master... probably one already exists');
|
|
} catch (err:Error) {
|
|
this.error(err);
|
|
}
|
|
|
|
this.registerWithMaster();
|
|
this.timer.start();
|
|
}
|
|
|
|
/**
|
|
* Register our client ID with the @{class:AphlictMaster} and send our
|
|
* subscriptions.
|
|
*/
|
|
private function registerWithMaster():void {
|
|
this.send.send('aphlict_master', 'register', this.client);
|
|
this.expiry = new Date().getTime() + (5 * AphlictClient.INTERVAL);
|
|
this.log('Registered client ' + this.client);
|
|
|
|
// Send subscriptions to master.
|
|
this.log('Sending subscriptions to master.');
|
|
this.send.send(
|
|
'aphlict_master',
|
|
'subscribe',
|
|
this.client,
|
|
this.subscriptions);
|
|
}
|
|
|
|
/**
|
|
* Send a keepalive signal to the @{class:AphlictMaster}.
|
|
*
|
|
* If the connection to the master has expired (because the master has not
|
|
* sent a heartbeat signal), then a new connection to master will be
|
|
* created.
|
|
*/
|
|
private function keepalive(event:TimerEvent):void {
|
|
if (new Date().getTime() > this.expiry) {
|
|
this.connectToMaster();
|
|
}
|
|
|
|
this.send.send('aphlict_master', 'ping', this.client);
|
|
}
|
|
|
|
/**
|
|
* This function is used to receive the heartbeat signal from the
|
|
* @{class:AphlictMaster}.
|
|
*/
|
|
public function pong():void {
|
|
this.expiry = new Date().getTime() + (2 * AphlictClient.INTERVAL);
|
|
}
|
|
|
|
/**
|
|
* Receive a message from the Aphlict Server, via the
|
|
* @{class:AphlictMaster}.
|
|
*/
|
|
public function receiveMessage(msg:Object):void {
|
|
this.log('Received message.');
|
|
this.externalInvoke('receive', msg);
|
|
}
|
|
|
|
}
|
|
|
|
}
|