1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 06:42:42 +01:00

Make Aphlict client somewhat more approachable

Summary: Provide a reasonable JS API for the Aphlict client. Provide an example behavior to invoke it.

Test Plan:
Ran "aphlict_server.js" with:

  $ sudo node aphlict_server.js

Loaded /aphlict/. Opened console. Got "hello" from the server every second.

Got reasonable errors with the server not present ("Security exception", but this is because it can't connect to port 843 to access the policy server).

Reviewers: ddfisher, keebuhm, allenjohnashton, btrahan

Reviewed By: btrahan

CC: aran, epriestley

Maniphest Tasks: T944

Differential Revision: https://secure.phabricator.com/D1800
This commit is contained in:
epriestley 2012-03-06 20:14:03 -08:00
parent 140927926d
commit f8431bbfee
13 changed files with 310 additions and 23 deletions

View file

@ -321,6 +321,17 @@ celerity_register_resource_map(array(
), ),
'disk' => '/rsrc/css/application/herald/herald-test.css', 'disk' => '/rsrc/css/application/herald/herald-test.css',
), ),
'javelin-aphlict' =>
array(
'uri' => '/res/50cae715/rsrc/js/application/aphlict/Aphlict.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/js/application/aphlict/Aphlict.js',
),
'javelin-behavior' => 'javelin-behavior' =>
array( array(
'uri' => '/res/0017f840/rsrc/js/javelin/lib/behavior.js', 'uri' => '/res/0017f840/rsrc/js/javelin/lib/behavior.js',
@ -331,6 +342,19 @@ celerity_register_resource_map(array(
), ),
'disk' => '/rsrc/js/javelin/lib/behavior.js', 'disk' => '/rsrc/js/javelin/lib/behavior.js',
), ),
'javelin-behavior-aphlict-listen' =>
array(
'uri' => '/res/6388e057/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-aphlict',
2 => 'javelin-util',
3 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
),
'javelin-behavior-aphront-basic-tokenizer' => 'javelin-behavior-aphront-basic-tokenizer' =>
array( array(
'uri' => '/res/9be30797/rsrc/js/application/core/behavior-tokenizer.js', 'uri' => '/res/9be30797/rsrc/js/application/core/behavior-tokenizer.js',
@ -1658,17 +1682,6 @@ celerity_register_resource_map(array(
), ),
'disk' => '/rsrc/css/application/slowvote/slowvote.css', 'disk' => '/rsrc/css/application/slowvote/slowvote.css',
), ),
0 =>
array(
'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-uri',
1 => 'javelin-php-serializer',
),
'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js',
),
'phabricator-standard-page-view' => 'phabricator-standard-page-view' =>
array( array(
'uri' => '/res/7e09bbfc/rsrc/css/application/base/standard-page-view.css', 'uri' => '/res/7e09bbfc/rsrc/css/application/base/standard-page-view.css',
@ -1892,6 +1905,17 @@ celerity_register_resource_map(array(
), ),
'disk' => '/rsrc/css/core/syntax.css', 'disk' => '/rsrc/css/core/syntax.css',
), ),
0 =>
array(
'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-uri',
1 => 'javelin-php-serializer',
),
'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js',
),
), array( ), array(
'packages' => 'packages' =>
array( array(

View file

@ -445,6 +445,7 @@ phutil_register_library_map(array(
'MetaMTAConstants' => 'applications/metamta/constants/base', 'MetaMTAConstants' => 'applications/metamta/constants/base',
'MetaMTANotificationType' => 'applications/metamta/constants/notificationtype', 'MetaMTANotificationType' => 'applications/metamta/constants/notificationtype',
'Phabricator404Controller' => 'applications/base/controller/404', 'Phabricator404Controller' => 'applications/base/controller/404',
'PhabricatorAphlictTestPageController' => 'applications/notifications/controller/test',
'PhabricatorAuditActionConstants' => 'applications/audit/constants/action', 'PhabricatorAuditActionConstants' => 'applications/audit/constants/action',
'PhabricatorAuditAddCommentController' => 'applications/audit/controller/addcomment', 'PhabricatorAuditAddCommentController' => 'applications/audit/controller/addcomment',
'PhabricatorAuditComment' => 'applications/audit/storage/auditcomment', 'PhabricatorAuditComment' => 'applications/audit/storage/auditcomment',
@ -621,6 +622,7 @@ phutil_register_library_map(array(
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view', 'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view',
'PhabricatorMetaMTAWorker' => 'applications/metamta/worker', 'PhabricatorMetaMTAWorker' => 'applications/metamta/worker',
'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/mysql', 'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/mysql',
'PhabricatorNotificationsController' => 'applications/notifications/controller/base',
'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/clientauthorization', 'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/clientauthorization',
'PhabricatorOAuthClientAuthorizationBaseController' => 'applications/oauthserver/controller/clientauthorization/base', 'PhabricatorOAuthClientAuthorizationBaseController' => 'applications/oauthserver/controller/clientauthorization/base',
'PhabricatorOAuthClientAuthorizationDeleteController' => 'applications/oauthserver/controller/clientauthorization/delete', 'PhabricatorOAuthClientAuthorizationDeleteController' => 'applications/oauthserver/controller/clientauthorization/delete',
@ -1247,6 +1249,7 @@ phutil_register_library_map(array(
'ManiphestView' => 'AphrontView', 'ManiphestView' => 'AphrontView',
'MetaMTANotificationType' => 'MetaMTAConstants', 'MetaMTANotificationType' => 'MetaMTAConstants',
'Phabricator404Controller' => 'PhabricatorController', 'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAphlictTestPageController' => 'PhabricatorNotificationsController',
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController', 'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
'PhabricatorAuditComment' => 'PhabricatorAuditDAO', 'PhabricatorAuditComment' => 'PhabricatorAuditDAO',
'PhabricatorAuditCommitListView' => 'AphrontView', 'PhabricatorAuditCommitListView' => 'AphrontView',
@ -1390,6 +1393,7 @@ phutil_register_library_map(array(
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAWorker' => 'PhabricatorWorker', 'PhabricatorMetaMTAWorker' => 'PhabricatorWorker',
'PhabricatorMySQLFileStorageEngine' => 'PhabricatorFileStorageEngine', 'PhabricatorMySQLFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorNotificationsController' => 'PhabricatorController',
'PhabricatorOAuthClientAuthorization' => 'PhabricatorOAuthServerDAO', 'PhabricatorOAuthClientAuthorization' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthClientAuthorizationBaseController' => 'PhabricatorOAuthServerController', 'PhabricatorOAuthClientAuthorizationBaseController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthClientAuthorizationDeleteController' => 'PhabricatorOAuthClientAuthorizationBaseController', 'PhabricatorOAuthClientAuthorizationDeleteController' => 'PhabricatorOAuthClientAuthorizationBaseController',

View file

@ -423,6 +423,8 @@ class AphrontDefaultApplicationConfiguration
'channel/(?P<channel>[^/]+)/' => 'channel/(?P<channel>[^/]+)/' =>
'PhabricatorChatLogChannelLogController', 'PhabricatorChatLogChannelLogController',
), ),
'/aphlict/' => 'PhabricatorAphlictTestPageController',
); );
} }

View file

@ -0,0 +1,37 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PhabricatorNotificationsController
extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->setApplicationName('Notifications');
$page->setBaseURI('/notifications/');
$page->setTitle(idx($data, 'title'));
$page->setGlyph('!');
$page->appendChild($view);
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorNotificationsController.php');

View file

@ -0,0 +1,56 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorAphlictTestPageController
extends PhabricatorNotificationsController {
public function processRequest() {
$instructions = '<h1>Check Your Javascript Console!</h1>';
$object_id = 'aphlictswfobject';
$content = phutil_render_tag(
'object',
array(
'classid' => 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000',
),
'<param name="movie" value="/rsrc/swf/aphlict.swf" />'.
'<param name="allowScriptAccess" value="always" />'.
'<embed src="/rsrc/swf/aphlict.swf" id="'.$object_id.'"></embed>');
Javelin::initBehavior(
'aphlict-listen',
array(
'id' => $object_id,
'server' => '127.0.0.1',
'port' => 2600,
));
return $this->buildStandardPageResponse(
array(
$instructions,
$content,
),
array(
'title' => 'Aphlict Test Page',
));
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/notifications/controller/base');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phutil', 'markup');
phutil_require_source('PhabricatorAphlictTestPageController.php');

View file

@ -17,7 +17,6 @@ set -x
-output aphlict.swf \ -output aphlict.swf \
-default-background-color=0x444444 \ -default-background-color=0x444444 \
-default-size=500,500 \ -default-size=500,500 \
-target-player=10.2.0 \
-warnings=true \ -warnings=true \
-debug=true \ -debug=true \
-source-path=$ROOT/externals/vegas/src \ -source-path=$ROOT/externals/vegas/src \
@ -25,3 +24,5 @@ set -x
src/Aphlict.as) src/Aphlict.as)
mv $BASEDIR/aphlict.swf $ROOT/webroot/rsrc/swf/aphlict.swf mv $BASEDIR/aphlict.swf $ROOT/webroot/rsrc/swf/aphlict.swf
# -target-player=10.2.0 \

View file

@ -27,9 +27,26 @@ package {
private var socket:Socket; private var socket:Socket;
private var readBuffer:ByteArray; private var readBuffer:ByteArray;
private var remoteServer:String;
private var remotePort:Number;
public function Aphlict() { public function Aphlict() {
super(); super();
ExternalInterface.addCallback('connect', this.externalConnect);
ExternalInterface.call(
'JX.Stratcom.invoke',
'aphlict-component-ready',
null,
{});
}
public function externalConnect(server:String, port:Number):void {
this.externalInvoke('connect');
this.remoteServer = server;
this.remotePort = port;
this.master = null; this.master = null;
this.receiver = new AphlictReceiver(this); this.receiver = new AphlictReceiver(this);
this.subjects = []; this.subjects = [];
@ -90,25 +107,33 @@ package {
socket.addEventListener(Event.CONNECT, didConnectSocket); socket.addEventListener(Event.CONNECT, didConnectSocket);
socket.addEventListener(Event.CLOSE, didCloseSocket); socket.addEventListener(Event.CLOSE, didCloseSocket);
socket.addEventListener(IOErrorEvent.IO_ERROR, didErrorSocket);
socket.addEventListener(ProgressEvent.SOCKET_DATA, didReceiveSocket); socket.addEventListener(ProgressEvent.SOCKET_DATA, didReceiveSocket);
socket.connect('127.0.0.1', 2600); socket.addEventListener(IOErrorEvent.IO_ERROR, didIOErrorSocket);
socket.addEventListener(
SecurityErrorEvent.SECURITY_ERROR,
didSecurityErrorSocket);
socket.connect(this.remoteServer, this.remotePort);
this.readBuffer = new ByteArray(); this.readBuffer = new ByteArray();
this.socket = socket; this.socket = socket;
} }
private function didConnectSocket(event:Event):void { private function didConnectSocket(event:Event):void {
this.log("Connect!"); this.externalInvoke('connected');
} }
private function didCloseSocket(event:Event):void { private function didCloseSocket(event:Event):void {
this.log("Close!"); this.externalInvoke('close');
} }
private function didErrorSocket(event:Event):void { private function didIOErrorSocket(event:IOErrorEvent):void {
this.log("Error!"); this.externalInvoke('error', event.text);
}
private function didSecurityErrorSocket(event:SecurityErrorEvent):void {
this.externalInvoke('error', event.text);
} }
private function didReceiveSocket(event:Event):void { private function didReceiveSocket(event:Event):void {
@ -126,7 +151,7 @@ package {
var msg_len:Number = parseInt(b.readUTFBytes(8), 10); var msg_len:Number = parseInt(b.readUTFBytes(8), 10);
if (b.length >= msg_len + 8) { if (b.length >= msg_len + 8) {
var bytes:String = b.readUTFBytes(msg_len); var bytes:String = b.readUTFBytes(msg_len);
var data:Object = JSON.deserialize(bytes); var data:Object = vegas.strings.JSON.deserialize(bytes);
var t:ByteArray = new ByteArray(); var t:ByteArray = new ByteArray();
t.writeBytes(b, msg_len + 8); t.writeBytes(b, msg_len + 8);
this.readBuffer = t; this.readBuffer = t;
@ -150,11 +175,15 @@ package {
} }
public function receiveMessage(msg:Object):void { public function receiveMessage(msg:Object):void {
this.log("Received message!"); this.externalInvoke('receive', msg);
} }
public function log(msg:String):void { public function externalInvoke(type:String, object:Object = null):void {
ExternalInterface.call('console.log', msg); ExternalInterface.call('JX.Aphlict.didReceiveEvent', type, object);
}
public function log(message:String):void {
ExternalInterface.call('console.log', message);
} }
} }

View file

@ -6,7 +6,7 @@ function getFlashPolicy() {
'<!DOCTYPE cross-domain-policy SYSTEM ' + '<!DOCTYPE cross-domain-policy SYSTEM ' +
'"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">', '"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">',
'<cross-domain-policy>', '<cross-domain-policy>',
'<allow-access-from domain="*" to-ports="*"/>', '<allow-access-from domain="*" to-ports="2600"/>',
'</cross-domain-policy>' '</cross-domain-policy>'
].join("\n"); ].join("\n");
} }

View file

@ -0,0 +1,74 @@
/**
* @provides javelin-aphlict
* @requires javelin-install
* javelin-util
*/
/**
* Simple JS API for the Flash Aphlict client. Example usage:
*
* var aphlict = new JX.Aphlict('aphlict_swf', '127.0.0.1', 2600)
* .setHandler(function(type, message) {
* JX.log("Got " + type + " event!")
* })
* .start();
*
* Your handler will receive these events:
*
* - `connect` The client initiated a connection to the server.
* - `connected` The client completed a connection to the server.
* - `close` The client disconnected from the server.
* - `error` There was an error.
* - `receive` Received a message from the server.
*
* You do not have to handle any of them in any specific way.
*/
JX.install('Aphlict', {
construct : function(id, server, port) {
if (__DEV__) {
if (JX.Aphlict._instance) {
JX.$E('Aphlict object is sort of a singleton..!');
}
}
JX.Aphlict._instance = this;
this._server = server;
this._port = port;
// Flash puts its "objects" into global scope in an inconsistent way,
// because it was written in like 1816 when globals were awesome and IE4
// didn't support other scopes since global scope is the best anyway.
var container = document[id] || window[id];
this._flashContainer = container;
},
members : {
_server : null,
_port : null,
start : function() {
this._flashContainer.connect(this._server, this._port);
}
},
properties : {
handler : null
},
statics : {
_instance : null,
didReceiveEvent : function(type, message) {
if (!JX.Aphlict._instance) {
return;
}
var handler = JX.Aphlict._instance.getHandler();
if (handler) {
handler(type, message);
}
}
}
});

View file

@ -0,0 +1,30 @@
/**
* @provides javelin-behavior-aphlict-listen
* @requires javelin-behavior
* javelin-aphlict
* javelin-util
* javelin-stratcom
*/
JX.behavior('aphlict-listen', function(config) {
function onready() {
JX.log("The flash component is ready!");
var client = new JX.Aphlict(config.id, config.server, config.port)
.setHandler(function(type, message) {
if (message) {
JX.log("Got aphlict event '" + type + "':");
JX.log(message);
} else {
JX.log("Got aphlict event '" + type + "'.");
}
})
.start();
}
// Wait for the element to load, and don't do anything if it never loads.
// If we just go crazy and start making calls to it before it loads, its
// interfaces won't be registered yet.
JX.Stratcom.listen('aphlict-component-ready', null, onready);
});

Binary file not shown.