經過使用HTTPService、WebService、URLLoader及FileReference等組件或類完成與服務器的通訊是很是方便和簡單的,但它們的缺點是通訊數據量較小,若是要傳輸大量的數據或實現不一樣對象的序列化傳輸,則知足不了需求,須要尋找另一種通訊協議,另外一種高效的傳輸協議代替SOAP協議傳輸的方案,那即是AMF協議。經過AMF協議實現RPC通訊功能,則稱爲AMF-RPC。在Java平臺可使用LCDS或BlazeDS實現AMF-RPC功能。java
不管是哪一種服務器端技術都可以很輕鬆地應用XML,由於XML 徹底是一個基於文本的協議。像 XML 這樣基於文本的協議的缺點是額外的數據抽象層的編寫與維護工做相對很沉重。此外,若是數據須要序列化和反序列化,那麼這個數據抽象層在客戶端和服務器端都會佔用不少資源。web
Flash Player 能夠支持另一種傳輸協議,這個協議可以緩解由基於文本的協議致使的傳輸瓶頸問題,可以幫助開發者以更簡單的方式與服務器交互。這就是 AMF(Action Message Format)。它是一個二進制格式的協議,可以替代用於傳輸XML的基於文本的協議而在 HTTP 協議之上交換數據。採用 AMF 的應用中,數據抽象層徹底能夠省去,客戶與服務器間的通信效率比傳統的應用基於文本的協議傳輸要高得多。數據庫
BlazeDS中包含了AMF 的 Java 實現,能夠用來與服務器端的Java對象遠程交互,也能夠用來在客戶端之間傳遞消息。開發人員能夠藉助 BlazeDS 的遠程技術簡單地調用 POJO、Spring 服務或EJB方法。開發人員能夠經過其消息系統從客戶端向服務器端發送消息,固然也可從服務器端向客戶端發送消息。編程
BlazeDS 也能夠與其餘一些消息系統結合使用,好比JMS、ActiveMQ。因爲其遠程技術與消息系統採用的方式是在 HTTP 協議上傳輸 AMF 數據,BlazeDS 所以在性能上擁有很大優點,同時也避免了額外的數據抽象層的處理工做。BlazeDS 在不少基於 Java 的應用服務器環境下都能正常工做,這些服務器包括 Tomcat、WebSphere、WebLogic、JBoss 以及 ColdFusion。此外,不管是 web(在 Flash Player 中運行)仍是桌面(在Adobe AIR下運行)的 Flex 應用程序中,BlazeDS 的使用都很簡單。後端
LCDS是一個JavaEE服務端組件,用於簡化Flex、Flash和AIR應用程序與JavaEE Web應用程序之間的大數據量通訊。經過LCDS與服務器端通訊,不但能夠大大提升通訊的效率,並且還能提供傳統B/S結構沒有的功能。準確地說,LCDS應該是一個代理網關,客戶端的Flex應用的程序對服務器端應用程序的請求必須通過該代理網關進行處理,在通過一系列複雜的處理,服務器響應後,再由該代理網關返回給Flex客戶端應用程序。安全
BlazeDS能夠當作是LCDS的一個子集,並且是一個開源產品,在通常的項目中徹底能夠替代LCDS。BlazeDS是一套面向ActionScript的先後臺通訊框架。在服務器端,BlazeDS以servlet的方式存在於Java應用服務器上。它默認提供三種服務,遠程調用、訪問代理和消息服務。同時,框架容許用戶添加自定義服務。服務器
BlazeDS 爲客戶端程序鏈接到服務端數據、並在多個客戶端和服務器間傳送數據提供了一系列的服務。BlazeDS 實現了客戶端之間的實時消息。網絡
一個BlazeDS 應用包括兩個部分:一個客戶端應用程序和一個服務端的J2EE 程序,架構以下圖:session
【客戶端程序】架構
BlazeDS 客戶端程序一般是一個Flex 或AIR 應用程序。Flex 和AIR 程序使用Flex 組件和BlazeDS 服務器通信,包括RemoteObject,HTTPService,WebService,Producer 和Consumer組件,HTTPService, WebService,,Producer 和Consumer 組件都是Flex SDK 的一部分。
儘管一般使用Flex 或AIR 開發客戶端程序,但也可聯合使用Flex,HTML,JavaScript技術。或者用HTML 和JavaScript 經過Ajax client library 與BlazeDS 通信。
【BlazeDS 服務端】
BlazeDS 服務端運行在J2EE 應用服務器上的WEB 應用中。BlazeDS 包含三個預約義的web 應用,能夠做爲開發自定義應用的基礎。
爲現存的J2EE web 應用配置BlazeDS 支持,執行如下步驟:
把BlazeDS 及其依賴的jar 包拷貝到WEB-INF/lib 下。
修改WEB-INF/flex 目錄下有關BlazeDS的配置文件。
在WEB-INF/web.xml 文件中定義MessageBrokerServlet 和一個session listener。
【BlazeDS 核心功能】
BlazeDS 核心功能包括RPC Services 和Messaging Service。
【RPC Services】
遠程過程調用(RPC)服務爲請求響應的應用而設計,提供了一種很好的訪問外部數據的選擇。客戶端程序使用RPC 服務發送異步請求給遠程服務,服務端處理請求請直接返回數據到客戶端。能夠經過客戶端RPC 組件獲取數據,客戶端組件包括HTTP GET or POST (HTTP services),SOAP (web services),Java objects (remote object services)。
須要提供企業級功能時可使用RPC 組件,如爲不一樣域間的傳輸提供代理,客戶端認證,RPC 服務白名單,服務端日誌,本地化支持,RPC 服務集中管理。經過BlazeDS 的RemoteObject 組件能夠訪問遠程的Java 對象,而不須要將其配置成WebServices。
客戶端的RPC 組件調用一個遠程服務,該組件將服務端的響應保存爲一個容易得到的ActionScript 對象。這種客戶端組件包括HTTPService, WebService 和RemoteObject 組件。
注意:能夠直接使用Flex SDK 直接調用HTTP 服務或WebService,而不須要經過BlazeDS 代理。但不能在BlazeDS 或ColdFusion 外使用RemoteObject 組件。
【消息服務】
消息服務可使客戶端程序經過往返的消息和服務端異步通信。消息屬性包括:一個惟一的消息ID、多個BlazeDS 消息頭、多個自定義的消息頭和消息正文。
客戶端程序調用消息生產者發送消息,能夠在Flex 程序中使用生產者組件定義一個生產者。客戶端程序調用消息消費者接受消息,能夠在Flex 程序中使用消費者組件定義一個消費者。消費者組件訂閱服務端地址,接收消息生產者發生到該地址的消息。
經過JMSAdapter 消息服務能夠橋接到內部或外部的JMS 的話題和隊列。橋接可讓Flex 客戶端程序和Java 客戶端程序交換信息。
【服務適配器】
BlazeDS 可讓你訪問不一樣的持久性數據存儲和數據庫包括JMS,以及其餘的數據持久化設備。服務適配器負責對特定的數據存儲服務器以相應的方式更新數據。經過適配器架構能夠定製集成任何類型的消息或後端存儲系統。
【消息基礎框架】
BlazeDS 使用以消息爲基礎的框架在客戶端和服務器之間發送往返消息。BlazeDS 在客戶端和服務器間使用兩種主要的交換模式。第一種模式是請求響應模式:客戶端發送一個請求給服務器處理,服務器返回一個包含處理結果的響應給客戶端。RPC 服務使用這種模式。
第二種模式是發送訂閱模式:當服務端路徑發佈消息給一系列訂閱該地址的客戶端,客戶端將收到該消息。消息服務使用這種模式推送消息給感興趣的客戶端。消息服務業使用請求響應模式下達命令,發佈消息以及和服務器交互數據。
【通道和端點】
客戶端使用通道經過網絡發送消息,一個通道封裝從服務,目的和應用代碼解耦出來的消息格式,網絡協議,網絡狀態。通道把消息格式化並翻譯成特定的網絡格式,傳遞到服務器上的一個端點。
而且通道對經由其發往服務器的消息強制指定一種規則,對相應的響應也採起該規則。規則對確保客戶端和服務器間交互的一致性,可預見的方式很是重要。
通道和服務器上基於Java 的端點通信。端點從新配置消息爲特定協議格式,傳遞普通的Java 格式的消息給消息中間人,消息中間人肯定消息發送到哪兒,並肯定到合適的服務終點的路徑。
【通道類型】
BlazeDS 包括幾種消息通道,包括標準的和安全的動做消息格式(AMF)通道,以及HTTP(AMFX)通道。AMF 和HTTP 通道支持非輪詢的請求響應模式和模擬即時消息的客戶端輪詢模式。AMF和HTTP通道爲實時消息提供實時數據流。
從官網上下載BlazeDS,選擇"Binary"版本。
打開下載的zip文件後,裏面會有一個"blazeds.war"文件。再用winrar解壓。
在Eclipse中新建一個Dynamic Web Project工程"FlexAndJava_Server"。新建包並命名爲"com.hebut.java",而後新建一個HelloWorld類。
HelloWorld.Java的內容以下所示:
package com.hebut.java;
public class HelloWorld {
public String getInfo(String info){
return "服務器:"+info;
}
}
HelloWorld類的內容很簡單,經過定義一個getInfo方法接收外部參數,返回字符串"服務器:"與外部參數鏈接的字符串。Flex客戶端調用這個方法得到返回結果。
解壓縮"blazeds.war"文件,將解壓後的WEN-INF目錄複製到Web工程的WebRoot目錄下(覆蓋原來的WEB-INF目錄)。以記事本格式打開"WebRoot\WEB-INF\flex\"目錄下的"remoting-config.xml"文件,在文件中定義一個遠程服務,這樣Flex應用程序才能調用這個遠程服務。
在<services>節點下加入<destination>元素,定義一個服務目標,程序以下所示:
<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service"
class="flex.messaging.services.RemotingService">
<adapters>
<adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter"
default="true"/>
</adapters>
<default-channels>
<channel ref="my-amf"/>
</default-channels>
<destination id="HelloWorld">
<properties>
<source>com.hebut.java.HelloWorld</source>
</properties>
</destination>
</service>
id屬性用於定義Flex應用程序能夠訪問的服務目標,source屬性定義該目標所指向的類。這裏HelloWorld即表明"com.hebut.java.HelloWorld"類。
至此,服務器端的程序已經開發完成,部署到Tomcat服務器目錄中,並啓動Tomcat。
在Flex中,實現AMF-RPC應用要經過<mx:RemoteObject>組件完成,使用該組件能夠訪問應用服務器上的類。定義格式以下:
<fx:Declarations>
<!-- 將非可視元素(例如服務、值對象)放在此處 -->
<s:RemoteObject id="組件ID" destination="服務目標" 屬性="屬性值" >
</s:RemoteObject>
</fx:Declarations>
destination屬性指定服務的目標,該屬性的值必定要和Java工程的"remoting-config.xml"中的destination的id同樣(安裝BlazeDS後添加的那一段)。
(1)endpoint:可以使開發人員在編譯或以編程方式建立ChannelSet時快速指定RemoteObject目標的端點,而無須引用服務配置文件。在實現Java平臺下的AMF-RPC應用時,該屬性的值指定的格式爲"/Java工程名/messagebroker/amf"。
(2)concurrency:指示如何處理對同一服務的多個調用的值,默認值爲multiple,表示不取消現有請求,由開發人員負責經過管理事件流確保返回數據的一致性。其餘有效值有single(每次只容許在此方法中發出一個請求);last(發出請求可致使客戶端忽略任何當前未處理請求的結果或錯誤)。
(3)requestTimeout:提供對已發送消息的請求超時(以秒爲單位)的訪問。
(4) showBusyCursor:若是值爲true,則在執行服務時顯示忙狀態光標,默認值爲false。
新建一個Flex項目,名稱爲"FlexAndJava_Client"。
單擊"下一步"按鈕設置程序的輸出目錄爲Web應用程序目錄,"根文件夾"設爲Tomcat服務器下的文件夾,以下圖所示。
而後設置界面以下所示。
源代碼以下:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955"
minHeight="600">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
protected function btnSend_clickHandler(event:MouseEvent):void
{
agent.getInfo(txtSend.text);
}
protected function agent_resultHandler(event:ResultEvent):void
{
txtReceive.text=event.result as String;
}
protected function agent_faultHandler(event:FaultEvent):void
{
Alert.show("失敗信息"+event.message.toString());
}
protected function btnClear_clickHandler(event:MouseEvent):void
{
txtSend.text="";
txtReceive.text="";
}
]]>
</fx:Script>
<fx:Declarations>
<!-- 將非可視元素(例如服務、值對象)放在此處 -->
<mx:RemoteObject id="agent" destination="HelloWorld"
result="agent_resultHandler(event)"
fault="agent_faultHandler(event)">
</mx:RemoteObject>
</fx:Declarations>
<s:Panel x="56" y="129" width="250" height="200" title="客戶發送端">
<s:Button id="btnSend" x="146" y="129" label="發送"
click="btnSend_clickHandler(event)"/>
<s:TextArea id="txtSend" x="8" y="11" width="232" height="106"/>
<s:Button id="btnClear" x="37" y="130" label="清空"
click="btnClear_clickHandler(event)"/>
</s:Panel>
<s:Panel x="390" y="129" width="250" height="200" title="客戶接收端">
<s:TextArea id="txtReceive" x="10" y="10" width="228"/>
</s:Panel>
</s:Application>
演示效果以下:
ps:
LCDS:http://baike.baidu.com/view/2121194.htm?fr=aladdin