摘要:Flash技術發展到今天,其語言經歷過三個版本,從最簡單的實現動畫的跳轉交互,到如今的大項目的開發。AMF的發展也經歷過兩個版本,從早期支持AS1.0和AS2.0的AMF0,到現在支持AS3.0的AMF3。該文詳細論述了AMF的功能及數據處理過程,并實現簡化AMF使用的自定義類。
關鍵詞:Flash Remoting;AMF;EventDispatcher
中圖分類號:TP317文獻標識碼:A文章編號:1009-3044(2010)05-1196-03
Under the AS3 Flash Remoting Custom Classes to Achieve
XIONG Huan-yan, XU Fang
(Jiangxi Modern Polytechnic College, Nanchang 330012, China)
Abstract: Flash technology developed to today, the language went through three versions, from the simplest realization of the jump animation interactive, to today's large project development. AMF development has also gone through two versions, from earlier AMF0 support AS1.0 and AS2.0, to the present AMF3 support AS3.0. This paper discusses in detail the functions of AMF and data processing, and the use of simplified AMF custom class.
Key words: Flash Remoting; AMF; EventDispatcher
1 Flash Remoting的核心技術:AMF
為了處理復雜數據類型,采用一種獨有的方式使Flash與應用服務器間可以來回傳送數據勢在必行。于是AMF應運而生。
AMF從早期的AMF0發展到現在的AMF3。AMF3用作AS 3.0的默認序列化格式,而AMF0則用作舊版的AS 1.0和2.0的序列化格式。在網絡傳輸數據方面,AMF3比AMF0效率更高。AMF3能將int和uint對象作為整數(integer)傳輸,并且能序列化AS 3.0才支持的數據類型, 比如ByteArray,XML和IExternalizable等。
2 AMF簡介
AMF(Action Message Format)是Adobe獨家開發出來的通信協議,它采用二進制壓縮,序列化、反序列化、傳輸數據,它是基于http協議的輕量級數據交換協議,從而為Flash 播放器與Flash Remoting網關通信提供了一種輕量級的、高效率的通信方式。
AMF可用于Flash Remoting、Local Connection和Flash Communication Server,它最大的特色在于可直接將Flash的內置對象(如Object, Array,String等)傳回服務器端,并且在服務器端自動進行解析成適當的對象(如Flash的數組傳回PHP時就會自動轉換為關聯數組),這個特色對開發者最大的好處在于不再需要人工處理 “序列化” 與 “反序列化”的繁復工作,不但精確度更高,同時開發也更省時間。
由于AMF是二進制格式并且編碼時經過高度壓縮,因此非常適合用來傳遞大量的資料,根據FlashORB網站的測試(主要針對Web Service與Flash Remoting進行測試),當數據量越大時,Flash Remoting的傳輸效率就越高,遠遠超過Web Service,至于XML、URLLoader,由于使用純文本的傳輸方式,效率就更不能與Flash Remoting相提并論了。
3 AMF內容處理過程
AMF的內容處理過程大致如下(如圖1所示):
1)客戶端以POST方式向服務器發送序列化請求數據流;
2)服務器端適配器對接收到的數據流進行反序列化,得到服務器端程序能夠識別的數據,并建立一個響應(Response)消息;
3)Debug開始;
4)對反序化后的數據進行各種處理,并得到返回值;
5)對響應流進行序列化;
6)將響應數據流發送Http響應給客戶端。
4 Flash Remoting的應用
Flash Remoting的調用實現都基于flash.net.NetConnection類和flash.net.Responder類。其中NetConnection類可以調用遠程應用程序服務器上的命令;Responder類提供了一個對象,該對象在NetConnection.call() 中使用以處理來自與特定操作成功或失敗相關的服務器的返回值,使用過程如下:
1)創建遠程服務器的連接對象:
var _connection:NetConnection = new NetConnection();
2)創建服務器返回值的處理對象:
_responder = new Responder(onResultHandler, onFaultHandler);
其中:如果對服務器的調用成功并返回結果,則調用自定義函數onResultHandler
如果服務器返回一個錯誤,則調用自定義函數onFaultHandler
3)連接遠程服務器網關:
_connection.connect(\"amfphp/getway.php\");
connect()方法并不會立即連接網關URL,如果URL不合法或服務器發生異常,都不會收到錯誤,直到真正調用方法之后。
4)調用遠程服務器上的命令
_connection.call(\"classPath.method\", _responder, 可選參數列表);
其中:第一個參數用點分隔符格式的路徑的形式指定遠程服務器的方法
第二個參數指定Responder對象,用于處理服務器的返回值
可選參數列表將若干可選參數傳遞給第一個參數所指定的方法
5)編寫自定義函數onResultHandler和onFaultHandler,分別用來處理成功返回結果或返回一個錯誤。如下所示:
function onResultHandler(resultData:*):void {
//resultData為調用成功后返回的結果,其數據類型為返回結果的類型
}
function onFaultHandler(faultData:Object):void {
//faultData為調用失敗后返回的錯誤對象
//其中faultData.description為調用失敗后返回的錯誤信息
}
5 Flash Remoting自定義類
從上述的實現過程來看,利用Flash Remoting調用遠程服務器命令,每次都要創建NetConnection和Responder兩個對象,并手動實現它們的連接,比較繁瑣。為了使得利用Flash Remoting調用遠程應用程序服務器上的命令更加方便實用,可創建一個自定義類對其進行封裝,完整的實現程序如下:
package {
import flash.net.NetConnection;
import flash.net.Responder;
import flash.events.*;
//自定義類FlashRemoting繼承自EventDispatcher類,使其具有調度事件的功能
public class FlashRemoting extends EventDispatcher {
private var _conn:NetConnection;
private var _responder:Responder;
private var _data:*;//存放調用遠程服務器命令成功后的返回值
public function FlashRemoting(gateway:String) {
_responder = new Responder(onResultHandler,onFaultHandler);
_conn = new NetConnection();
_conn.connect(gateway);
_conn.addEventListener(NetStatusEvent.NET_STATUS,nsHandler);
}
//調用遠程服務器上的命令,第一個參數為服務器命令名,
//后面若干可選參數為傳遞給服務器命令的參數
public function call(classFunc:String, ...args):void {
var parameters:Array = args;
parameters.unshift(classFunc, _responder);
_conn.call.apply(this, parameters);
}
//(只讀屬性)獲取調用遠程服務器命令成功后的返回值
public function get data():* {
return _data;
}
//調用成功后接收返回值,并調度Event.COMPLETE事件
private function onResultHandler(resultData:*):void {
_data = resultData;
var tmpEvt:Event = new Event(Event.COMPLETE);
dispatchEvent(tmpEvt);
}
//調用失敗后調度ErrorEvent.ERROR事件
private function onFaultHandler(faultData:Object):void {
var tmpEvt:ErrorEvent = new ErrorEvent(ErrorEvent.ERROR);
tmpEvt.text = faultData.description;
dispatchEvent(tmpEvt);
}
private function nsHandler(evt:NetStatusEvent):void {
trace(event.info.code);
}
}
}
編寫好后,在程序中利用自定義類FlashRemoting調用遠程服務器端命令的方法如下(以下以PHP的amfphp為例,實現調用PHP的HelloWorld類中的say方法):
var fr:FlashRemoting = new FlashRemoting(\"amfphp/gateway.php\");
fr.addEventListener(Event.COMPLETE, onResultHandler);
fr.addEventListener(ErrorEvent.ERROR, onErrorHandler);
function onResultHandler(evt:Event):void{
trace(evt.target.data);
}
function onErrorHandler(evt:ErrorEvent):void{
trace(evt.text);
}
fr.call(\"HelloWorld.say\");
6 與后端集成
Flash是前端的界面技術,而后端和數據庫交互或大型運算依然需要依托Java、.Net、PHP、Ruby等語言。早在Flash MX的時候Adobe就提出AMF技術,即將Java等語言的對象轉換為ActionScript對象的技術規范。Adobe官方推出了Data Services 2,支持了AMF等功能,但是價格昂貴。在開源方面,PHP有專門支持的AmfPHP,另外WebORB同時支持.Net、Java、PHP、Ruby。
7 結束語
通過AMF協議,Flash可直接訪問服務器端返回的數據類型,相比URLLoader返回的單一的String類型,大大節省了類型轉換和格式化數據所耗費的大量時間。AMF采用二進制壓縮,使得數據在傳輸時更加安全可靠。
參考文獻:
[1] 孫穎.Flash ActionScript3殿堂之路[M].北京:電子工業出版社,2007.
[2] 林嚇洪.ActionScript3.0編程精髓[M].北京:機械工業出版社,2008.