-
-
Save vrobel/643492 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.robotlegs.utilities.remote | |
{ | |
import com.adobe.serializers.json.JSONDecoder; | |
import mx.collections.ArrayCollection; | |
public class JsonRemoteService extends RemoteServiceBase | |
{ | |
public function JsonRemoteService(rootURL:String = "") | |
{ | |
super(rootURL); | |
} | |
override protected function generateObject(data:*):Object | |
{ | |
// Hack: | |
if (data == "[]") | |
return new ArrayCollection(); | |
return new JSONDecoder().decode(String(data)); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.robotlegs.utilities.remote { | |
public interface NetConnectionService { | |
function call(gatewayUrl:String, remoteMethod:String, ...rest):Promise | |
function closeConnection(gatewayUrl:String) : void | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.robotlegs.utilities.remote { | |
import flash.events.NetStatusEvent; | |
import flash.events.SecurityErrorEvent; | |
import flash.net.NetConnection; | |
import flash.net.ObjectEncoding; | |
import flash.net.Responder; | |
import flash.utils.Dictionary; | |
public class NetConnectionServiceBase implements INetConnectionService { | |
protected var netConnections:Dictionary; | |
protected var promises:Array; | |
public function NetConnectionServiceBase() { | |
netConnections = new Dictionary(); | |
promises = [] | |
} | |
public function call(gatewayUrl:String, remoteMethod:String, ...rest):Promise { | |
var nc:NetConnection = getNetConnection(gatewayUrl); | |
var p:Promise = request(nc, remoteMethod, rest); | |
nc.addEventListener(NetStatusEvent.NET_STATUS, createHandler(handleNetStatus,p), false, 0, true); | |
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, createHandler(handleSecurityError,p), false, 0, true); | |
return p; | |
} | |
private function getNetConnection(gatewayUrl:String):NetConnection { | |
if(netConnections[gatewayUrl]) | |
return netConnections[gatewayUrl]; | |
else { | |
var nc:NetConnection = new NetConnection(); | |
nc.objectEncoding = ObjectEncoding.AMF3; | |
nc.connect(gatewayUrl); | |
netConnections[gatewayUrl] = nc; | |
return nc; | |
} | |
} | |
public function closeConnection(gatewayUrl:String) : void { | |
if(netConnections[gatewayUrl]) { | |
(netConnections[gatewayUrl] as NetConnection).close(); | |
delete netConnections[gatewayUrl]; | |
} | |
} | |
protected function request(nc:NetConnection, rm:String, params:Array):Promise { | |
var p:Promise = new Promise; | |
var res:Responder = new Responder(createHandler(handleComplete, p), createHandler(handleIoError, p)); | |
nc.call.apply(this, [rm, res].concat(params)); | |
promises.push(p); | |
return p; | |
} | |
protected function releasePromise(promise:Promise):void { | |
var index:int = promises.indexOf(promise); | |
if (index != -1) { | |
promises.splice(index, 1); | |
} | |
} | |
/* ----------- HANDLERS ----------- */ | |
private function handleNetStatus(e:Object, promise:Promise):void { | |
switch (e.info.code) { | |
case "NetConnection.Call.Failed": | |
releasePromise(promise); | |
promise.handleFault({ error: "NetConnection Error", message: 'NetConnection call failed' }); | |
break; | |
case "NetConnection.Connect.Failed": | |
releasePromise(promise); | |
promise.handleFault({ error: "NetConnection Error", message: 'NetConnection connect failed' }); | |
break; | |
} | |
} | |
private function handleSecurityError(e:Object, promise:Promise):void { | |
releasePromise(promise); | |
promise.handleFault({ error: "Security Error", message: String(e.text) }); | |
} | |
protected function handleIoError(e:Object, promise:Promise):void { | |
releasePromise(promise); | |
promise.handleFault({ error: "IO Error", message: String(e.faultString + " ON " + e.faultDetail + " " + e.faultCode) }); | |
} | |
protected function handleComplete(r:Object, promise:Promise):void { | |
releasePromise(promise); | |
promise.handleResult( generateObject( r ) ); | |
} | |
/* ----------- END HANDLERS ----------- */ | |
protected function createHandler(listener:Function, promise:Promise):Function { | |
return function(obj:Object):void { | |
listener(obj, promise); | |
} | |
} | |
protected function generateObject(data:*):Object { | |
return Object(data); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.robotlegs.utilities.remote | |
{ | |
public class Promise | |
{ | |
public static var PENDING:String = "pending"; | |
public static var COMPLETE:String = "complete"; | |
public static var FAILED:String = "failed"; | |
public static var CANCELLED:String = "cancelled"; | |
protected var resultHandlers:Array; | |
protected var faultHandlers:Array; | |
[Bindable] | |
public var status:String; | |
[Bindable] | |
public var result:*; | |
[Bindable] | |
public var fault:*; | |
public function Promise() | |
{ | |
status = PENDING; | |
resetHandlers(); | |
} | |
public function addResultHandler(handler:Function):Promise | |
{ | |
if (status == COMPLETE) | |
{ | |
handler(this); | |
} | |
else if (status == PENDING && resultHandlers.indexOf(handler) == -1) | |
{ | |
resultHandlers.push(handler); | |
} | |
return this; | |
} | |
public function addFaultHandler(handler:Function):Promise | |
{ | |
if (status == FAILED) | |
{ | |
handler(this); | |
} | |
else if (status == PENDING && faultHandlers.indexOf(handler) == -1) | |
{ | |
faultHandlers.push(handler); | |
} | |
return this; | |
} | |
public function handleResult(obj:Object):void | |
{ | |
status = COMPLETE; | |
result = obj; | |
var len:int = resultHandlers.length; | |
for (var i:int = 0; i < len; i++) | |
{ | |
var handler:Function = resultHandlers[i]; | |
handler(this); | |
} | |
resetHandlers(); | |
} | |
public function handleFault(obj:Object):void | |
{ | |
status = FAILED; | |
fault = obj; | |
var len:int = faultHandlers.length; | |
for (var i:int = 0; i < len; i++) | |
{ | |
var handler:Function = faultHandlers[i]; | |
handler(this); | |
} | |
resetHandlers(); | |
} | |
public function cancel():void | |
{ | |
status = CANCELLED; | |
resetHandlers(); | |
} | |
protected function resetHandlers():void | |
{ | |
resultHandlers = []; | |
faultHandlers = []; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.robotlegs.utilities.remote | |
{ | |
public interface RemoteService | |
{ | |
function get(url:String):Promise; | |
function post(url:String, params:Object = null):Promise; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.robotlegs.utilities.remote | |
{ | |
import flash.events.Event; | |
import flash.events.IOErrorEvent; | |
import flash.events.ProgressEvent; | |
import flash.events.SecurityErrorEvent; | |
import flash.net.URLLoader; | |
import flash.net.URLRequest; | |
import flash.net.URLRequestMethod; | |
import flash.net.URLVariables; | |
import flash.utils.Dictionary; | |
public class RemoteServiceBase implements RemoteService | |
{ | |
protected var loaders:Dictionary; | |
protected var promises:Array; | |
protected var rootURL:String; | |
public function RemoteServiceBase(rootURL:String = "") | |
{ | |
this.loaders = new Dictionary(); | |
this.promises = new Array(); | |
this.rootURL = rootURL; | |
} | |
public function get(url:String):Promise | |
{ | |
var req:URLRequest = new URLRequest(fullUrl(url)); | |
return request(req); | |
} | |
public function post(url:String, params:Object = null):Promise | |
{ | |
var req:URLRequest = new URLRequest(fullUrl(url)); | |
var vars:URLVariables = new URLVariables(); | |
// Flash Player seems to perform a GET if no params are passed | |
params ||= {forcePost:true}; | |
for (var prop:String in params) | |
vars[prop] = params[prop]; | |
req.data = vars; | |
req.method = URLRequestMethod.POST; | |
return request(req); | |
} | |
protected function request(req:URLRequest):Promise | |
{ | |
var promise:Promise = new Promise(); | |
var loader:URLLoader = new URLLoader(); | |
loader.addEventListener(Event.COMPLETE, createHandler(handleComplete, promise)); | |
loader.addEventListener(IOErrorEvent.IO_ERROR, createHandler(handleIoError, promise)); | |
loader.addEventListener(ProgressEvent.PROGRESS, createHandler(handleProgress, promise)); | |
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, createHandler(handleSecurity, promise)); | |
promises.push(promise); | |
loaders[promise] = loader; | |
loader.load(req); | |
return promise; | |
} | |
protected function releasePromise(promise:Promise):void | |
{ | |
var index:int = promises.indexOf(promise); | |
if (index != -1) | |
{ | |
promises.splice(index, 1); | |
delete loaders[promise]; | |
} | |
} | |
protected function createHandler(listener:Function, promise:Promise):Function | |
{ | |
return function(event:Event):void | |
{ | |
listener(event, promise); | |
} | |
} | |
protected function handleSecurity(e:SecurityErrorEvent, promise:Promise):void | |
{ | |
releasePromise(promise); | |
promise.handleFault({error: "Security Error", message: e.text}); | |
} | |
protected function handleProgress(e:ProgressEvent, promise:Promise):void | |
{ | |
// promise.handleProgress({bytesTotal: e.bytesTotal, bytesLoaded: e.bytesLoaded}); | |
} | |
protected function handleIoError(e:IOErrorEvent, promise:Promise):void | |
{ | |
releasePromise(promise); | |
promise.handleFault({error: "IO Error", message: e.text}); | |
} | |
protected function handleComplete(e:Event, promise:Promise):void | |
{ | |
releasePromise(promise); | |
promise.handleResult(generateObject(e.target.data)); | |
} | |
protected function fullUrl(url:String):String | |
{ | |
if (url == null || url.length == 0) | |
return null; | |
return url.indexOf("://") > -1 ? url : rootURL + url; | |
} | |
protected function generateObject(data:*):Object | |
{ | |
return Object(data); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@wrobel221 I've moved this stuff into a new RL extension called Oil: http://github.com/darscan/robotlegs-extensions-Oil
Feel free to fork from there.