AS3版Flash Remoting客户端类-Service类
这段时间在研究Flash Remoting技术,之前在Flash里调用Remoting的话,只能通过NetConnection类调用,但写起来比较麻烦,同时方法调用不直观。
而在Flex里用RemoteObject类用起来比较直观,但它是集成在Flex里了,功能还挺复杂,还在Flash里不方便调用,所以我参考RemoteObject类写了一个简化的AS3版类-Service类,我现在把相关代码共享出来。
Service类
package com.klstudio.net.remoting {
import flash.net.NetConnection;
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.events.AsyncErrorEvent;
import flash.events.IOErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.utils.flash_proxy;
import flash.utils.Proxy;
import flash.utils.Dictionary;
/**
* Remoting服务
* @author Kinglong([email protected])
* @since:2010-8-3
*/
[Event(name="fault", type="com.klstudio.events.FaultEvent")]
[Event(name="result", type="com.klstudio.events.ResultEvent")]
[Event(name="netStatus", type="flash.events.NetStatusEvent")]
[Event(name="ioError", type="flash.events.IOErrorEvent")]
[Event(name="securityError", type="flash.events.SecurityErrorEvent")]
dynamic public class Service extends Proxy implements IEventDispatcher {
private var _gateway : String;
private var _nc : NetConnection;
private var _destination : String;
private var _dispatcher : EventDispatcher;
private var _operations : Dictionary;
/**
* 构建
* @param gateway remoting网关地址
* @param destination remoting目标地址
* @param objectEncoding remoting编码(amf0/amf3)
*/
public function Service(gateway : String,destination : String,objectEncoding : uint = 3) {
_operations = new Dictionary(true);
_gateway = gateway;
_destination = destination;
_dispatcher = new EventDispatcher(this);
_nc = new NetConnection();
_nc.client = this;
_nc.objectEncoding = objectEncoding;
_nc.addEventListener(NetStatusEvent.NET_STATUS, ncHandler);
_nc.addEventListener(IOErrorEvent.IO_ERROR, ncHandler);
_nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, ncHandler);
_nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, ncHandler);
_nc.connect(_gateway);
}
/**
* public
*/
/**
* 设置安全证书的用户名和密码
* @param userName 用户名
* @param password 密码
*/
public function setRemoteCredentials(userName : String,password : String) : void {
_nc.addHeader("Credentials", false, { userid : userName, password : password });
}
/**
* remoting网关地址
*/
public function get gateway():String{
return _gateway;
}
/**
* remoting目标地址
*/
public function get destination():String{
return _destination;
}
public function set destination(value:String):void {
_destination = value;
}
/**
* remoting编码
*/
public function get objectEncoding():uint{
return _nc.objectEncoding;
}
public function set objectEncoding(value:uint):void{
_nc.objectEncoding = value;
}
/**
* remoting连接
*/
public function get connenction():NetConnection{
return _nc;
}
public function toString() : String {
return "[Service gateway="+gateway+", destination="+destination+", objectEncoding="+objectEncoding+"]";
}
/**
* private
*/
private function ncHandler(event : Event) : void {
switch(event.type){
case AsyncErrorEvent.ASYNC_ERROR:
break;
default:
dispatchEvent(event);
}
}
private function getOperation(name:String):Operation{
var operation:Operation = _operations[name];
if(operation == null) {
operation = new Operation(this,name);
_operations[name] = operation;
}
return operation;
}
private function getLocalName(name:*):String{
if(name is QName){
return QName(name).localName;
}
return String(name);
}
/**
* proxy
*/
override flash_proxy function getProperty(name : *) : * {
return getOperation(getLocalName(name));
}
override flash_proxy function callProperty( methodName : *, ...parametres : * ) : * {
return getOperation(getLocalName(methodName)).send.apply(null,parametres);
}
/**
* IEventDispatcher
*/
public function dispatchEvent(event : Event) : Boolean {
// TODO: Auto-generated method stub
return _dispatcher.dispatchEvent(event);
}
public function hasEventListener(type : String) : Boolean {
// TODO: Auto-generated method stub
return _dispatcher.hasEventListener(type);
}
public function willTrigger(type : String) : Boolean {
// TODO: Auto-generated method stub
return _dispatcher.willTrigger(type);
}
public function removeEventListener(type : String, listener : Function, useCapture : Boolean = false) : void {
_dispatcher.removeEventListener(type, listener, useCapture);
}
public function addEventListener(type : String, listener : Function, useCapture : Boolean = false, priority : int = 0, useWeakReference : Boolean = false) : void {
_dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
}
}
}
</textarea>
<br />
Operation类<br />
<textarea name="code" class="java" cols="45" rows="5">package com.klstudio.net.remoting {
import com.klstudio.events.FaultEvent;
import com.klstudio.events.ResultEvent;
import flash.net.Responder;
import flash.events.EventDispatcher;
/**
* Operation
* @author Kinglong([email protected])
* @since:2010-8-3
*/
[Event(name="fault", type="com.klstudio.events.FaultEvent")]
[Event(name="result", type="com.klstudio.events.ResultEvent")]
public class Operation extends EventDispatcher {
private var _service:Service;
private var _name:String;
private var _responder:Responder;
public function Operation(service:Service,name:String) {
_service = service;
_name = name;
_responder = new Responder ( resultHandler, statusHandler );
}
/**
* public
*/
public function get service():Service{
return _service;
}
public function get name():String{
return _name;
}
public function send(...args:Array):void{
var params:Array = [_service.destination + "." + _name,_responder];
params = params.concat(args);
_service.connenction.call.apply(_service.connenction,params);
}
override public function toString():String{
return "[Operation name="+name+"]";
}
/**
* private
*/
private function resultHandler(info:Object):void{
var event:ResultEvent = new ResultEvent(ResultEvent.RESULT, info);
if(hasEventListener(ResultEvent.RESULT)){
dispatchEvent(event);
}else {
_service.dispatchEvent(event);
}
}
private function statusHandler(info:Object):void{
var fault:Fault = new Fault(info["code"], info["message"],info["details"]);
var event:FaultEvent = new FaultEvent(FaultEvent.FAULT, fault);
if(hasEventListener(FaultEvent.FAULT)){
dispatchEvent(event);
}else{
_service.dispatchEvent(event);
}
}
}
}
</textarea>
<br />
Fault类<br />
<textarea name="code" class="java" cols="45" rows="5">package com.klstudio.net.remoting {
/**
* Fault
* @author Kinglong([email protected])
* @since:2010-8-3
*/
public class Fault extends Error {
public var rootCause : Object;
public var content : Object;
protected var _faultCode : String;
protected var _faultString : String;
protected var _faultDetail : String;
public function Fault(faultCode : String, faultString : String, faultDetail : String = null) {
super("faultCode:" + faultCode + " faultString:\'" + faultString + "\' faultDetail:\'" + faultDetail + "\'");
_faultCode = faultCode;
_faultString = faultString ? (faultString) : ("");
_faultDetail = faultDetail;
}
public function get faultString() : String {
return _faultString;
}
public function toString() : String {
var str : String = "[Fault";
str = str + (" faultString=\"" + faultString + "\"");
str = str + (" faultCode=\"" + faultCode + "\"");
str = str + (" faultDetail=\"" + faultDetail + "\"]");
return str;
}
public function get faultCode() : String {
return _faultCode;
}
public function get faultDetail() : String {
return _faultDetail;
}
}
}
</textarea>
<br />
FaultEvent类<br />
<textarea name="code" cols="45" rows="5" class="java">package com.klstudio.events {
import com.klstudio.net.remoting.Fault;
import flash.events.Event;
/**
* FaultEvent
* @author Kinglong([email protected])
* @since:2010-8-3
*/
public class FaultEvent extends Event {
public static const FAULT : String = "fault";
public var fault : Fault;
public function FaultEvent(type : String, fault : Fault,bubbles : Boolean = false, cancelable : Boolean = false) {
super(type, bubbles, cancelable);
this.fault = fault;
}
}
}
</textarea>
<br />
ResultEvent类
<br />
<textarea name="code" class="java" cols="45" rows="5">package com.klstudio.events {
import flash.events.Event;
/**
* ResultEvent
* @author Kinglong([email protected])
* @since:2010-8-3
*/
public class ResultEvent extends Event {
public static const RESULT:String = "result";
public var result : Object;
public function ResultEvent(type : String, result : Object,bubbles : Boolean = false, cancelable : Boolean = false) {
super(type, bubbles, cancelable);
this.result = result;
}
}
}
</textarea>
<br />
调用实例<br />
<textarea name="code" class="java" cols="45" rows="5">package test {
import com.klstudio.events.FaultEvent;
import com.klstudio.events.ResultEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import com.klstudio.net.remoting.Service;
import flash.display.Sprite;
/**
*
* @author Kinglong([email protected])
* @since:2010-8-3
*/
public class TestRemoting extends Sprite {
private var _service:Service;
public function TestRemoting() {
_service = new Service("http://localhost:8080/test/messagebroker/amf","Remoting");
_service.addEventListener(FaultEvent.FAULT, faultHandler);
stage.addEventListener(MouseEvent.CLICK, stageHandler);
}
private function stageHandler(event:Event):void{
_service.getTitle.addEventListener(ResultEvent.RESULT,getTitleHandler);
_service.getTitle();
}
private function getTitleHandler(event:ResultEvent):void{
trace("result>" + event.result);
}
private function faultHandler(event:FaultEvent):void{
trace(event.fault.toString());
}
}
}