Flash Remoting 教學 1 - 下載、安…

来源:互联网 发布:远程视频监控软件 编辑:程序博客网 时间:2024/05/18 03:40

◆flash remoting是什麼?

Flash remoting是一種連接flash client 與server端的技術,它的功用就像是 web service, xml,loadVars一般,可以在兩者之間交換資料,達到動態置換內容的目地。

Flashremoting特別的地方在於它採用macromedia獨家的AMF(ActionMessage Format),這是一種 binaryformat的資料型態,透過 AMF overHTTP的方式將flash端資料編碼後傳回server,server端的remotingadaptor接收到資料後則會解碼回正確的native物件,交給正確的程式處理。

AMF除了用於Flash remoting外,也廣泛的用於 LocalConnection 與 Flash communicationserver,它最大的特色在於可直接將flash nativeobject,例如Object, Array, Date,XML,傳回server端,並且在server端自動進行轉譯成適當的物件,例如flash的Array傳回PHP時就會自動轉換為 AssociativeArray;這個特色對開發者最大的好處在於不需要再人工處理serialization與deserialization的繁複工作,不但精確度更高,同時開發也更省時間。

由於AMF是binaryformat並且編碼時經過高度壓縮,因此非常適合用來傳遞大量的資料,根據flashorb網站的測試(主要針對webservice與flash remoting),當資料量越大時,flashremoting的傳輸效能就越高,遠遠超過webservice的表現,因此同樣的道理也可得知xml, loadVars,loadVariables 等使用plaine textformat的傳輸方式自然也無可比擬。

至於在server端,目前macromedia官方支援的平台有三種,分別是JavaColdfusion(但實際上Coldfusion應該只算是java的subset,它是一種scripting taglibrary)與.NET,但由於AMF格式已被玩家反組譯成功,因此很快的就在OpenSource圈出現各種「民間版」的remoting替代方案,其中比較有名的是:

-AMFPHP:這是php版的remoting
-OPENAMF:java版的remoting
-Flap:Perl 與Python版的remoting
-FlashORB:商業版的remoting替代方案,目前支援java與.net

相關閱讀:
十個採用remoting的理由:

◆amfphp是平麼?

本文主要介紹的是php平台上的remoting方案,也就是amfphp。

Amfphp最早是由JustinWatkins所發起並負責撰寫第一版大部份的程式碼,經過三年發展後去年由PatrickMineault接手,不但改良了大部份的程式碼,同時也補齊了許多重要的功能,例如本系列第二篇要介紹的pageable recordset。

Amfphp是一個完全由php寫成的server端模組,最大的特色在於完全不用安裝,任何hosting主機只要能跑php就能執行flashremoting,再加上php原本就有廣大的使用者基礎,因此一推出後很快就獲得玩家們的接受。

如果你想要瞭解amfphp的最新方展,可前往 amfphpwiki一探究竟,如果你有使用上的疑問,最好的解答就在amfphpmailing list 或是 forum 。

◆下載amfphp

目前amfphp最新版為 v1.0 milestone2,據patrick的說這應該是正式發表前最後一個beta版,所以穩定性應該相當不錯才是。

下載位址

◆安裝amfphp

檔案抓回來後解壓縮,應該會得到下圖的結構:

其中flashservices就是amfphp的核心模組,只要將它上傳到網頁的根目錄下即可。本文是以windows+ apache 2為例,因此放置位為:

C:\Program Files\Apache Group\Apache2\htdocs\flashservices

其中htdocs即是apache預設的網頁根目錄,如果你的位置不同請適當修改。
放好flashservices後基本核心就已完成,但這不代表就可以開始使用,我們還要為每個專案建立專屬的資料夾來放置其它必備的檔案。

◆第一個程式:hello world

這裏我們用一個實際的helloworld範例來示範如何讓flash 與php透過amfphp進行溝通。

首先我們在剛才的網頁根目錄下(htdocs)建一個專案資料夾,名稱為hello,完整路徑為:
C:\Program Files\Apache Group\Apache2\htdocs\hello

然後請下載本文的範例檔案zip檔,將裏面的東西全部解壓縮到hello資料夾內,此時資料夾的內容應該如下圖:

◆ Amfphp gateway的設定

接者我們就仔細看看裏面有些什麼東西,首先我們來看gateway.php,程式碼如下:

PLAIN TEXT
PHP:
  1. <?php
  2.         include"../flashservices/app/Gateway.php";
  3.         $gateway= newGateway();
  4.         $gateway->setLooseMode(true);
  5.     $gateway->setCharsetHandler("iconv","UTF-8", "UTF-8");
  6.     $gateway->setWebServiceHandler('php5');
  7.         $gateway->setBaseClassPath("services/");
  8.         $gateway->service();
  9. ?>

這裏新手最常錯的地方就是第一行,include的設定。一般由於flashservices核心模組都是放置於webserver的根目錄,因此每個專案的子資料夾只要用相對路徑..就可以存取到。但如果你的flashservices路徑不一樣,這裏就要做適當的修改,例如在我使用的hosting主機上(使用linux系統),這個路徑就可能變成:

/home/userrname/website.url/user/apache/htdoc/flashservices

總之這裏請小心確認路徑無誤。

接者第5行的設定也很重要,這裏主要是在設定php該用何種語系處理資料,它的標準格式如下:

setCharsetHandler(string mode, string phpCharset, stringsqlCharset)

第一個參數是設定要使用何種方式來重新編碼傳輸的資料,如果是php5的話則可以放使用iconv,這是內建的模組。

第二個參數是設定系統預定的文字編碼方式,如果要用中文的話就改成utf-8。

第三個參數是設定該如何處理sql queryresult,也就是recordset的文字編碼,同樣的要用中文請設定成utf-8。

本來這裏還有第四個參數,是設定 wsCharset (webservicecharset),但從ms1版本開始這個參數已被預設為utf-8,將來不論是使用SoapClient或nusoap都會自動讀取 phpCharset的設定為預設值。

所以總之照範例裏的設定直接套用就一定不會錯

最後看一下第7行,這裏是設定server端的程式位置,一般也就是businesslogic的所在地,或是businessdelegate的class位置(如果你希望將server端的logic儘量隱藏起來只透過單一管道供flash呼叫的話,這裏就是下手的好地方),預設值是server,這也就是為何解壓縮範例檔後會出現一個同名資料夾的原因。

&#9670;php class的內容

接者我們看一下service資料夾內的Hello.php,這個就是server端的程式,它的地位相當於coldfusion裏的component(CFC)或java裏的java bean。

它的程式碼如下:

PLAIN TEXT
PHP:
  1. <?
  2. class Hello
  3. {
  4.     //constructor
  5.     functionHello()
  6.     {
  7.         $this->methodTable= array(
  8.             "sayHello"=> array(
  9.                 "description"=> "Return hellomessage to client",
  10.                 "access"      => "remote",
  11.                 "arguments"   => array("")
  12.             ),
  13.         );
  14.     }
  15.     //remotemethod
  16.     functionsayHello($msg)
  17.     {
  18.         return"Amfphp welcomes you: " .$msg . " current time_" . time();
  19.     }
  20. }
  21. ?>

如果你有撰寫phpclass的經驗,應該馬上會發現這個Hello就是一個標準的php class檔,透過classkeyword來宣告class的啟始,並且在constructor裏有一個methodtable描述整個class要供外界操作的method。

注意這個methodtable裏還有許多關鍵字可用,在未來的教學文章裏會依序介紹。這裏我們只用到description,access,arguments三樣。其中access一定要設定成remote,這個method才能為外界所存取,不然就會出現錯誤訊息。

第17行開始我們寫了一個sayHello($msg),它會接收遠端傳來的一個參數$msg,然後我們將這個$msg加料後再傳回去。加料的部份是19行最後的time(),我們將目前server的時間傳回flash。

&#9670;flash端程式

接者我們看一下flash端的程式。首先請注意我在timeline的第1格用include的方式將程式碼加進去,這樣我就不用在flash裏可憐的寫程式碼,而可以用eclipse或primailscirpt等超強無敵編輯器快樂的寫作;所以你要找程式碼的話,直接打開code.as這個檔案即可。

Code.as的內容:

PLAIN TEXT
Actionscript:
  1. //remoting relatedclasses
  2. import mx.remoting.Service;
  3. import mx.remoting.PendingCall;
  4. import mx.remoting.RecordSet;
  5. import mx.remoting.debug.NetDebug;
  6. import mx.rpc.RelayResponder;
  7. import mx.rpc.ResultEvent;
  8. import mx.rpc.FaultEvent;
  9. //start debugging so we cansee debug info in NCD.
  10. NetDebug.initialize();
  11. //gatewaysettings
  12. var gateway:String = "http://localhost/hello/gateway.php";
  13. respGeneral = newRelayResponder(this, "resultReceived", "resultFailure");
  14. _service = new Service(gateway, null, "Hello", null,respGeneral);
  15. //callback when result wasreturned from server
  16. functionresultReceived(re:ResultEvent):Void{
  17.     trace("messagefrom server> " + re.result);
  18.     //phpreturns time in seconds, but flash Date class needs ms hence *1000
  19.     vartmp = re.result.split("_")[1]*1000;
  20.     trace("servertime> " + new Date(tmp));
  21. };
  22. //send message toserver
  23. btnSend.clickHandler = function(){
  24.     varpc:PendingCall = _service.sayHello(inputText.text);
  25. }

一開始我們先將flashremoting需要的class都import進來,這裏要注意的是,flashremoting需要另外下載與安裝,下載的方式有兩種:

1、 下載flash remoting components (v2)並裝入flash
2、 下載flash remoting sources並解壓縮到 mx目錄下。

第一種方式比較簡單,只要安裝mxp即可將remoting元件裝入flash,日後使用時只要直接拖放這個元件到畫面上即可。第二種方式則是直接取回remotingclasses並放入flash預設的mx路徑中,這樣做的好處有很多,例如可以三不五時修改一些地方以符合自已的需求,或是將來想用FAME開發時,也可以讓MTASC正確的編譯。

這裏我假設你已經裝好flash remoting元件的版本,在components裏也可以看到 flash remotingconnector這個元件。

第17行我們啟動NetDebug這個偵錯程式,它會將所有的傳輸交易訊息都顯示在NetConnectionDebugger(開啟方式 Window > Other Panel> NetConnection Debugger)裏,方便除錯,它是工程師的好朋友,實在不能一天沒有它…

第20行開始我們設定了將來連線的路徑,注意裏面的hello就是當初我們在htdocs裏建的hello資料夾,而gateway.php就是前一節所介紹的php檔案。

第21行我們設定了一個generalresponder,也就是一個catch-all的回應物件,只要server端有回傳訊息,就由這裏設定的兩支function去承接與處理。當然remoting處理回傳訊息的方式還有很多種,這裏因為是helloworld級的範例就先按下不表。

第22行我們建立了一個 _serviceobject,這是模擬遠端class的一個物件,請特別注意第三個參數Hello,它是指 C:\Program Files\ApacheGroup\Apache2\htdocs\hello\services\Hello.php也就是前一節介紹過的php class。

經過這三行的設定,我們就完成flash內的連線設定,接下來就可以開始呼叫遠端的method囉!

我們先跳到第33行,這裏我們設定了一個按鈕,當按下時它會執行
var pc:PendingCall = _service.sayHello(inputText.text);
也就是透過先前建立的_serive物件去呼叫server端的sayHello method,並且將文字框內輸入的內容傳回去。

這邊另外要注意的是PendingCall的使用,由於我們可能同時對server發生多個request,但遠端連線回應的速度通常不是即時的,因此需要PendingCall來個別指定每個request的callbackfunction,將來一堆訊息傳回時才能正確的處理。

最後我們回到第25行,這個function就是負責接收並處理server回傳資料的地方。首先我們在第26行將server傳回的訊息直接trace出來,注意這裏要使用re.result才能存取到正確的訊息,這是常見的錯誤之一。
接者第28、29行則是將php傳回的datestring轉換回flash的Date格式,由於php是以string的方式處理時間格式,因此這裏我們得辛苦點自已將它再轉回Dateobject。

到這裏程式碼就告一個段落,我們來執行看看吧!

這是程式執行的畫面,我們輸入一些文字後按下send.

這是flash將輸入文字傳回php的畫面,請注意參數部份正是我們輸入的文字

這是php回傳訊息的畫面,訊息的尾端已加上系統的時間

&#9670;ending

這個例子中我們很簡單的跑了一遍flash + amfphp +php的執行範例,從flash傳一個文字串回php,並從php傳一個date物件回來。

在真實案例中面對的情況往往會比這個複雜許多,例如至少會跟database互動撈資料互傳,或是進行authentication的認証等,但這些都是後話,在之後的範例中都會解釋。

本文的範例檔案下載。

ps.如果你遇到任何執行上的問題歡迎隨時發問,但請提供必要的背景資料給我,例如使用的作業系統、webserver, php版本,amfphp版本以及錯誤訊息、代號或程式碼行數,這樣我能更快瞭解你的問題所在也才能提供正確的答案。

by jeremy
体验新版博客
原创粉丝点击