#眉標=Flash #副標=Rich internet application #大標= Flash Remoting締造不同平台之豐富網站應用系統 #作者=文/宋志峰 #引言=本文將針對Macromedia的Flash Remoting技術,來看Flash Remoting可以帶給我們什麼新的思維與作法,並比較Flash Remoting在各平台上開發的差異比較。 #內文起=   說到Flash相信大家絕對不陌生,不管是生動活潑的Flash動畫,或是書店琳瑯滿目的Flash書籍,Flash簡直就成為網際網路服務上不可或缺的元素,其實這樣的結果是淺而易見的,因為Flash提供了跨平台、高品質、圖檔小和優異的多媒體互動功能,賦予了網站多彩多姿的視聽效果,本文將針對Macromedia的Flash Remoting技術,來看Flash Remoting可以帶給我們什麼新的思維與作法,並比較Flash Remoting在各平台上開發的差異比較。 #中標=Flash不只是Flash   大家對Flash的認知,大多停留在認為Flash是一套簡單的動畫軟體,如果您也這麼覺得的話,那可就大錯特錯了,Flash絕對不只是一套簡單的動畫軟體,Flash已經發展成一套複雜的工具,它除了本身具有可程式化的ActionScript(Flash 2004 MX後已經升級成ActionScript 2.0),還可以與動態資料庫網站整合,以達到多樣化的網路應用,這就是Macromedia所提倡的Rich Internet Application,而這背後使用的技術正是Flash Remoting,那Flash Remoting到底是什麼東西呢? 它又能完成什麼工作呢?在我們開始了解Flash Remoting之前,不如先到Macromedia所製作的寵物商店(http://www.macromedia.com/devnet/mx/blueprint/)來體驗Flash Remoting的魔力。 (pic01.tiff) -----box----- #圖1 Macromedia所製作的寵物商店電子商務網站範例。 -----end-----   在您試用過這個寵物商店之後,您應該會蠻驚訝的,原來購物網站也可以做的如此有聲有色。在這個電子商務中,所有的元件都是採用Flash來製作的,您可以在同一頁面下,完成瀏覽商品、購買商品及結帳的動作,透過實際的操作,相信您也會被Flash Remoting生動的魔力所深深吸引。 #中標=認識Flash Remoting   在Flash MX以前,Flash若要與伺服器做資料連結,主要是透過查詢字串與XML文件來處理,但是這兩種方法的缺點就是皆為純文字的資料格式,不論是Flash與Application Server之間誰要傳遞資料,都必須先經過繁複的手續來將資料轉換成查詢字串與XML之後,再由接收端還原成可用的資料,如此一來不但傳遞速度很慢,而且也使得設計上變得相當繁瑣;Flash Remoting可以說是建立網站服務的一種新建構思維,透過Flash Remoting您可以建立複雜的Client/Server應用程式,而且,在網頁上的呈現就像一般桌上應用程式介面一樣生動活潑,也能使Flash與伺服器之間傳遞資訊的過程,變得更容易也更有效率,圖2就是一個Flash Remoting的架構,筆者用廣義的角度來解釋這張架構圖,要實現Flash Remoting,我們必須在Flash Player與Application Server之間安裝一個Flash Remoting gateway,它主要負責三個主要的工作如下: 1. 處理由Flash Player所要求的Remote服務,這個服務可以從同一台伺服器上的Flash Remoting gateway上,或是由外部的Web Services而來。 2. 轉換由Flash Player送至Application Server的要求與資料(資料型態)。 3. 轉換由Application Server送至ActionScript的資料(資料型態)。 (pic02.tiff) -----box----- #圖2 Flash Remoting的架構。 -----box-----   您可能會注意到為何我會在2與3項工作內容寫「資料(資料型態)」,其實原因很簡單,在這裡是我想要強調,Flash ActionScipt與Application Server的資料型態並不是完全一樣的,畢竟這是兩個不同的環境,但是Flash Remoting gateway會將對等的資料型態進行轉換,以方便彼此之間來轉換與傳遞資料。 #中標=Flash Remoting應用程式的架構   當我們實際利用Flash與Server來建立網路應用程式,通常會跟隨圖3這樣的N-tiered架構,這個架構主要分成Presentation tier(表現層:Flash Player)、Middle tier(邏輯層:Flash Remoting gateway與Application Server)和Data tier(資料層:資料庫、XML或其他資料來源)。 (pic03.tiff) -----box----- #圖3 N-tiered的架構。 -----end-----   Presentation tier是應用程式的使用者人機介面(UI)和用戶端所需要的邏輯,可與Middle tier透過AMF(註1)來溝通;Middel tier介於Presentaion layer與Data source之間,可以使用ColdFusion MX、ASP.NET、Java、PHP來實現,它可以使用好幾層來組成抽象的層次,主要負責應用程式運作的核心邏輯關係;Data tier是最底層的階層,主要是負責管理系統所需的資料,我們可以用像是SQL Server、DB2、MySQL、Oracle、XML等來實現該層;每一個tier可以為了特殊的目的或是環境來進行最佳化,當使用Flash於Presentaion layer時這尤其重要,我們將核心的邏輯集中在Middle tier,可以與Presenation tier隔離,使得問題得以孤立,部署更加容易,各部分能獨立測試與開發,也更容易更新與維護,依循這樣的架構的想法,定義清楚的商業邏輯,能使得您所設計的應用程式更具規模,讓系統也更加條理分明。 -----box----- 註1 AMF是二位元格式的資料,它比字串為底的編碼還小,在傳送時需要的 頻寬較少,可以使得讀取跟回應時間縮短。 -----end----- #中標=Flash Remoting支援的平台與實作比較   Flash Remoting支援現今多數主流網站的應用程式伺服器技術,其中包含了ColdFusion MX、.NET與Java,我們利用一個最經典簡單的Hello World範例,可以讓讀者在深入Flash Remoting之前,親自體驗Flash Remoting於各平台程式撰寫的差異,在接下來的文章中,將會用ColdFusion MX、Server-Side ActionScript、Java、ASP.NET、PHP和SOAP-base Web Services來實行Hello World的Flash Remoting。   在開始前請讀者先注意到,由於這期我們不打算直接一股腦的埋入程式碼中,所以就不針對程式碼一一詳細解說,筆者將這部份留到下期再做深入的介紹,希望讀者能把注意力放在平台差異的比較上;開發Flash Remoting的應用程式,必須要有Macromedia Flash MX (2004 MX)和Flash Remoting的元件(可於http://www.macromedia.com/software/flashremoting/downloads/components/免費下載使用)。 下載安裝完元件後就可以使用Flash來開發Flash Remoting的程式,程式1就是用ActionScript 1.0所編寫,他主要負責建立與Flash Remoting gateway的連結,並且執行呼叫(引用)與顯示回應。在開始撰寫前,必須先在Flash開啟一個新的圖層(如圖4)取名為Action,當然您可以取您喜歡的名字,目的只是在做識別之用,並開啟ActioScript編輯的頁面,輸入本文中的程式碼1,在範例中的myURL是定義Flash Remoting gateway的URL位置,其中的localhost是指gateway在本機上,如果讀者的gateway是設置在其他台伺服器上,請改為該台的IP位址或是Domain name,myServicePath是指伺服器提供服務程式的位置結構,myResult.onResult負責處理成功的動作,而myResult.onStatus則負責處理錯誤的動作。 -----box----- #程式1用戶端的Flash ActionScript code (HelloWorld.fla)。 #include "NetServices.as" var myURL = "http://localhost/flashservices/gateway"; var myServicePath = "RIA.FlashRemoting.HelloWorld"; myResult = new Object( ); myResult.onResult = function (data) { trace("從Application Server回收的訊息: " + data); }; myResult.onStatus = function (info) { trace("一個錯誤發生: " + info.description); }; System.onStatus = myResult.onStatus; var myServer = NetServices.createGatewayConnection (myURL); var myService = myServer.getService(myServicePath, myResult); myService.sayHello( ); -----end----- (pic04tiff) -----box----- #圖4 Flash使用ActionScript建立Flash Remoting。 -----end----- #小標=ColdFusion MX   上一步驟,完成了用戶端的Flash程式,再來我們還必須完成伺服器端的邏輯部分,程式2是ColdFusion MX的程式碼,由於ColdFusion MX本身已經內建了Flash Remoting gateway,所以不需要再另外安裝即可運作。在此例中我們使用ColdFusion Componet (CFC)來編寫程式,它的內容十分簡單,就是直接傳回字串"Hello World from ColdFusion Component"。 在這裡需要注意的是這個HelloWorld.cfc必須擺在wwwroot\RIA\FlashRemoting\下(因為程式碼1中已經將服務位址定義於該處),如果成功的話,執行Flash將回跳出一個視窗,顯示其內容為「從Application Server回收的訊息: Hello World from ColdFusion Component」;當然ColdFusion MX要完成Flash Remoting絕對不只有使用CFC一途,且ColdFusion MX還能當成Flash Client與Java Object的中介者,這些我們會在以後的文章再度拿出來一一詳細解說。 -----box----- 程式2 伺服器端的ColdFusion MX code (HelloWorld.cfc) -----end----- #小標=ActionScript   在ColdFusion MX和JRun4的Application Server,提供開發者於伺服器端使用ActionScript建立Remote服務,這使得Flash MX的程式設計師,可以在不需要懂得任何伺服器端程式語言(例如CFML或Java)的狀況下,就可以完成伺服器端邏輯程式的撰寫,如程式3,就是一個用ActionScript所完成的Server-side ActionScript。 您會發現這跟我們在Flash中所使用的ActionScript沒什麼不一樣,如果成功的話,執行Flash將回跳出一個視窗顯示其內容為「從Application Server回收的訊息: Hello World from Server-Side ActionScript」;但是必須注意的是,當您用ActionScript來撰寫程式碼只能經由Flash Remoting來與Flash溝通,而不能像其他伺服器程式能直接輸出HTML的結果。另外要注意的,如果在同一個目錄下,一樣有一個叫HelloWorld.cfc存在的話,必須先將HelloWorld.cfc改名成其他名子,並充新啟動ColdFusion MX Server,如此HelloWorld.asr才能正常被Flash所使用,否則HelloWorld.cfc將會被ColdFusion MX Server所快取住,而導致HelloWorld.asr無法被取用。 -----box----- #程式3 伺服器端的ActionScript code (HelloWorld.asr)。 function sayHello ( ) { return "Hello World from Server-Side ActionScript"; } -----end----- #小標=Java   要使用Java來實現Flash Remoting,需要先行安裝Flash Remoting gateway在Java的應用伺服器(例如Macromedia's JRun4或IBM WebSphere)上,關於這部份的資訊與下載試用版可至http://www.macromedia.com/software/flashremoting/來做進一步的了解。 程式4是一個用Java所撰寫的程式碼,我們必須先將HelloWorld.java進行編譯,然後放在網站伺服器的classpath,這個路徑可能會依伺服器而有所不同,但是在JRun中通常WEB-INF或SERVER-INF作為起始目錄,然後再包含了伺服器的classpath。舉例來說,若我們要用JRun4來編譯HelloWorld.java,則可以用下面的命令來編譯c:\jrun4\servers\myservername\server-inf\classes\ria\ flashremoting\ >javac HelloWorld.java,如果成功的話,執行Flash將回跳出一個視窗顯示其內容為「從Application Server回收的訊息: Hello World from Java」;如同之前一樣,如果您使用JRun4和ActionScript的環境來建立過HelloWorld.asr的話,在編譯HelloWorld.java之前,必須要先將HelloWorld.asr更名。 -----box----- #程式4 伺服器端的Java code (HelloWorld.java)。 package RIA.FlashRemoting; public class HelloWorld { public String sayHello ( ) { return "Hello World from Java"; } } -----end----- #小標=ASP.NET   ASP.NET可以使用許多種語言來開發它,例如VB.NET或C#.NET等,在本例中我們使用C#來作撰寫的語法,在建立時我們可以使用微軟的VS.NET (Miacrosoft Visual Studio .NET)來作開發工具,選擇Project Types: Visual C# Projects,然後在Templates中選擇Class Library,並將檔案存檔成HelloWorld.cs。 ASP.NET的程式如程式6,它的功能一樣是負責回傳一段"Hello World from ASP.NET DLL"的訊息,當我們用VS.NET編譯過HelloWorld.cs以後,將會產生一個HelloWorld.dll,您將可以在projectpath/bin/Debug的目錄下找到它,複製這個檔案到wwwroot/flashservices/bin下,因為我們在程式碼中設定了namespace,所以我們不用更改Flash中的myServicePath,但是需要更改myURL的定義,這個是跟之前比較不一樣的部份,程式碼應該改成程式碼5: -----box----- #程式5 Client-side ActionScript針對ASP.NET所做的更改。 var myURL="http://localhoast/flashremoting/ gateway.aspx"; -----end-----   如果成功的話,執行Flash將回跳出一個視窗顯示其內容為「從Application Server回收的訊息: Hello World from ASP.NET DLL」;以上對程式碼所做的改變是無可避免的,因為.NET版本的Flash Remoting gateway不同於Java和ColdFusion MX的版本。 -----box----- #程式6 伺服器端的ASP.NET C# code (HelloWorld.cs)。 using System; namespace RIA.FlashRemoting { public class HelloWorld { public String sayHello ( ) { return "Hello World from ASP.NET DLL"; } } } -----end----- #小標=PHP   跟其他環境下相比,在PHP的環境下必須要作較多且較大的變化,因為FlashRemoting是以class為基礎的,在撰寫過程中需要參考到AMFPHP library,所以所有的Flash Remoting服務都必須在PHP中寫入class,當建立一個PHP的remote服務時,您應該要在wwwroot\RIA\FlashRemoting的目錄下寫入一個gateway.php,它的程式內容為程式7,負責建立Flash Remoting gateway和包含需要的檔案。 -----box----- #程式7 伺服器端的PHP Remoting gateway code (gateway.php)。 setBaseClassPath('/services/RIA/FlashRemoting'); $gateway->service( ); ?> -----end-----   接著再同樣的目錄下建立一個HelloWorld.php的檔案,程式內容為程式9,然後在回到Flash中更改myURL的定義,將位置指向AMFPHP gateway,其程式碼改為如程式碼8: -----box----- #程式8 Client-side ActionScript針對PHP所做的更改。 var myURL="http://localhoast/flashremoting/ gateway.php"; -----end----- -----box----- #程式9 伺服器端的PHP code (HelloWorld.php)。 methodTable = array( 'sayHello' => array( 'description' => 'Says Hello from PHP', 'access' => 'remote', 'arguments' => array ('arg1') ) ); } function sayHello ( ) { return 'Hello World from PHP'; } } ?> -----end-----   如果成功的話,執行Flash將回跳出一個視窗顯示其內容為「從Application Server回收的訊息: Hello World from PHP」的訊息;如同ASP.NET一樣,以上這些改變是必須的,因為PHP是利用PHP網頁來處理gateway的功能。 #小標=WebSerivces   在此Web Services的範例中,我們將使用ColdFusion MX來建立此Web Services,其實只要任何有sayHello()方法的Web Services都可以正常運作,我們選用ColdFusion MX來建立Web Services其實是有原因的,因為利用ColdFusion MX來建立Web Services相當的方便,我們只要將程式2的HelloWorld.cfc在URL後加上?wsdl(例如http://cfx.anistar.biz/ria/flashremotion/helloworld.cfc?wsdl)即可直接拿來使用,當您在瀏覽器輸入上述的網址,應該會顯示如下列程式10的Web Services WSDL XML文件。 -----box----- #程式10 伺服器端的Web Services。   最後回到Flash的ActionScript中,更改myServicePath的定義,將定義改成程式碼11,指向Web Services的WSDL檔,當我們選用Web Services來實現Flash Remoting時,您將不會受到程式語言的限制,您可以使用Python、Perl、C、C++或是任何可以擁有SOAP library的程式語言,如果成功的話,執行Flash將回跳出一個視窗顯示其內容為「從Application Server回收的訊息: Hello World from Web Services」的訊息;如果您想多認識Web Service可以參閱http://www.xml.com/webservices。 -----box----- #程式11 Client-side ActionScript針對Web Services所做的更改。 var myServicePath="http://localhoast/ria/flashremoting/ helloworld.cfc?wsdl"; -----end----- #小標=除錯注意事項   最後,如果您在測試這些範例時無法正常執行,且錯誤訊息為"service cannot be found",那請注意服務的路徑是否和Flash中的myURL或myServicePath一樣,若是其他問題請看看是否有之前建立過同名稱的範例而造成錯誤,例如HelloWorld.asr和HelloWorld.cfc存在同一目錄並擁有相同的檔名;另外也請讀者注意每種平台不同特性須對Flash本身的ActionScript或是伺服器端的位置服務有所修改。 #中標=結語   最後我們針對各平台做一個整合性的綜合比較,表1從Flash Remoting在各平台使用上設計的難易度的層面來做評估,再針對各平台的優缺點來進行說明與評量。 -----box----- #表1 Flash Remoting在各平台上設計的難度。 Application Server種類  Flash Remoting 設計的難易 ColdFusion MX 簡易 Server-side ActionScript 簡易 Java 中等 ASP.NET 中等 PHP 較麻煩 Web Services 簡易 -----end-----   ColdFusion MX的優點是本身已經包含了Flash Remoting gateway,所以不需要再額外購買Macromedia Flash Remoting MX即可運作,ColdFusion本身的程式碼相當容易撰寫,開發迅速,可以透過ColdFusion Componets (CFCs)和ColdFusion Pages來與Flash做溝通,而且連結Flash也不需要透過過多複雜的設定,只需要增加一點Flash Remoting的概念,就能快速上手,不過缺點是ColdFusion MX本身跟其他平台比較起來較為昂貴,初期成本可能會比較高。   Server-side ActionScript的優點就是可以在ColdFusion MX或JRun4上面執行,不需額外購買或安裝Flash Remoting gateway,而且不需要會其他的伺服器端程式語言即可進行邏輯程式製作,而且不像Java或ASP.NET需要編譯後才能執行,在特殊功能的程式碼撰寫方面,有時會比其他語言方便(因為ActionScript可與Flash緊密的結合在一起),但是缺點是ActionScript無法自己獨立執行,它只能透過Flash Remoting來給予Flash使用,而且本身不能容許include其他ActionScript檔案,使得限制較多。   Java的優點是程式碼簡單,而且資源取得方便,Java只要將邏輯程式寫成Java class並且編譯過後放在指定的位置即可運作,可惜缺點是不同的Java平台再設定上可能會有些微的差距,並不是那麼統一,且若不是在JRun4上面執行,還需另外購買安裝Flash Remoting gateway才能與Flash作Flash Remoting,將會額外增加成本。   ASP.NET的優點是可以使用不只一種語言來進行開發,執行效能不錯,且具有物件導向的觀念,本身可以透過ASP.NET Pages與DLL來處理Flash Remoting,可是缺點是需額外購買Flash Remoting gateway,且ASP.NET一次只能回應一個用物件包裝起來的回傳值,開發者也需要較多的開發時間來實行Flash Remoting。   PHP的優點在於是免費的,也不需要額外購買Flash Remoting gateway,且國內有許多學習的資源,提供的虛擬伺服器主機眾多且較便宜,但缺點是需安裝AMFPHP(可至http://www.amfphp.org下載),而且需額外製作gateway.php,整體在使用PHP來實行Flash Remoting並不如其他平台上方便。   Web Services的優點在於它是一個公定的標準,可以用各種支援的程式來撰寫邏輯,且不受工作平台的限制,不但可以供Flash Remoting所使用,也可以供給其他程式或系統使用,且不需另外安裝Flash Remoting gateway和修改即可執行,使得Web Services在Flash Remoting的使用上相當方便,可惜缺點是Web Services在傳遞上較會緩慢,所以若是非常注重效率的前提下,比較不建議使用Web Services來實行。   另外Flash Remoting在各平台的路徑命名方式也各有差異,在這裡所提的路徑是指Flash透過Flash Reomting跟Gateway要求的服務路徑,簡單的來說就是程式1中myServicePath所設定的路徑,各平台的差異請參考表2。 -----box----- #表2 Flash Remoting在各平台上的命名路徑 環境 服務類別 服務路徑 ColdFusion MX ColdFuison pages 由網站初始目錄開始的目錄路徑 Colf Fusion MX CFC 由網站初始目錄開始的目錄路徑包含ColdFusion Componet (.cfc)的檔名 Server-side ActionScript SSAS 由網站初始目錄開始的目錄路徑包含ActionScript (.asr)的檔名 J2EE EJB 由EJBHome所結合的JNDI名稱 J2EE Java class 由合法的Java class的名稱 J2EE JavaBean 由合法的Java class的名稱 J2EE Servlet 由網站初始目錄開始的目錄路徑 JRun4 JMX MBean物件名稱 ASP.NET ASP.NET page 由網站初始目錄開始的目錄路徑 ASP.NET DLL 由合法的class的名稱 PHP PHP page (class) 由網站初始目錄開始的目錄路徑 Web Services Web Services 由提供Web Services的網站的.wsdl檔案的URL路徑 -----end-----   表2分別對環境、服務類別和服務路徑來做比較,環境是指伺服器端所使用的Application Server,服務類別是指提供服務之Applcation Server,當中所使用的服務類別型態,由這個表您可以知道各個平台是如何來支援Flash Remoting的。 在這裡主要有兩個重點,分別是各平台的服務類別與服務路徑,不僅各平台服務路徑的命名方式不一樣,同平台下不同的服務類別也可能會有差異,以ColdFusion MX為例,它的服務類別有CFM與CFC(註2)兩種,若是以CFM的方式來撰寫Flsah Remoting,則它的服務路徑如圖5一樣,程式碼1中的myService物件所呼叫的sayHello即是sayHello.cfm本身,若是以CFC的方式來撰寫Flsah Remoting,則它的服務路徑就會像圖6一樣,是呼叫HelloWorld.cfc中的sayHello( )函數。不管我們用什麼程式語言或平台開發,其概念是類似的,當在撰寫Flash Remoting程式時必須注意我們利用的服務類別,並將相對映的服務路徑寫在Flash中,才能正確的運作。 -----box----- #圖5 ColdFusion MX CFM的服務路徑。 (pic05.tiff) -----end----- -----box----- #圖6 ColdFusion MX CFC的服務路徑。 (pic06.tiff) -----end----- -----box----- 註2 ColdFusion MX中的CFM就如一般動態網頁一樣,而CFC就如物件導向中class的觀念。 -----end-----   剛剛我們就服務路徑做了討論,最後我們針對服務類別作個簡單的比較,就如之前註2的解說一樣,有些平台提供了不只一種服務類別來讓使用者撰寫,在此我們還是以ColdFusion MX為例,雖然CFM (ColdFusion Pages)比CFC (ColdFusion Components)在撰寫上來的簡單與直覺,而且於ColdFusion MX下如果具有相同服務名稱時,也會先以CFM最為第一首要使用對象,再來是CFC,最後才是Server-side Action Script (這是ColdFusion Server尋找服務的排列順序),但是筆者依然會建議讀者使用CFC(類似class的觀念的方式)來進行開發伺服器端的應用程式,為什麼呢?這是因為CFC比CFM要來的有結構有規模多了。 舉例來說,一個CFC可以包含多個個別獨立的邏輯函數,他們可以分別處理Flash Remoting的服務,但是CFM最多只能描述一種邏輯,另外CFC本身就擁有可重複使用的特性,以同一單一邏輯為例,如果我們用CFC來開發邏輯程式,則該開發出來的CFC不但可以給Flash Remoting所使用,在不用經過任何修改的狀況下,同時也能供CFM所引用,相反的如果我們用CFM來開發邏輯程式,則該開發出來的CFM只能供Flash Remoting所使用,如果要另作他途,則必須經過一段修改才能使用。由上述的描述就會不難發現為什麼筆者會建議使用CFC來進行開發而不用CFM了,如果您希望您的程式好維護又能重複使用的話,CFC絕對是開發的第一首選。   雖然在這裡我們都使用ColdFusion來作為解說(因為ColdFusion在Flash Remoting應用上最具代表性),但是在其他平台上的觀念都是大同小異的,尤其是大家所熟悉的.NET平台上,您將會看到這段結語的印證,也希望藉由本篇的介紹,能讓您更近一步的了解Flash Remoting與各平台之間所持有的特性,使未來當您要面對這塊領域時,預先知道您需要什麼與將要面對什麼,作為下定策略決策的依據。 責任編輯/黃雅惠 -----box----- 作者介紹 宋志峰 畢業於國立臺北大學資訊管理研究所,學經歷橫跨資訊工程與管理,並從事資訊系統開發工作多年,專長在處理跨平台和異質資訊系統整合的解決方案,平時致力於利用軟硬體資訊技術,嘗試以最佳方法解決商業應用,目前擔任MMUG特約講師。 -----end-----