AMF(Action Message Format)在開發Flash/Flex應用中使用頻率是非常高的,相對普通的HTTP、WebService的SOAP等多種數據通信方式的效率更高,有人曾經做過這方面的測試,詳細可以訪問:
http://xinsync.xju.edu.cn/index.php/archives/2162。本文將結合FluorineFx來提供通信服務接口,在客戶端通過Flex來訪問,簡單的介紹下關于使用FluorineFx的AMF(Action Message Format)協議通信的用法。
首先建立一個FluorineFx服務庫,并建立一個數據傳輸對象(DTO),為該對象添加[FluorineFx.TransferObject]表示該對象可以用作于FluorineFx的數據傳輸對象,這個對象將會在本文后面用到,如下代碼塊:
namespace FxDotNet.Services.DTO
{
[FluorineFx.TransferObject]
public class Book
{
public int ID { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public double Price { get; set; }
public Book()
{ }
public Book(int id, string name, string author, double price)
{
this.ID = id;
this.Name = name;
this.Author = author;
this.Price = price;
}
}
}
接下來就需要提供一個FluorineFx的遠程服務(即標記有[RemotingService]的對象),通過該服務提供對外訪問的方法接口,如下代碼塊:
namespace FxDotNet.Services
{
[RemotingService]
public class DataServices
{
public DataServices()
{
}
/// <summary>
/// 獲取服務端的系統時間
/// </summary>
/// <returns></returns>
public string GetServerTime()
{
return DateTime.Now.ToString();
}
public ArrayCollection GetBooks()
{
ArrayCollection array = new ArrayCollection();
array.Add(new Book(1, "三國演義", "羅貫中", 100.00));
array.Add(new Book(2, "西游記", "吳承恩", 200.00));
array.Add(new Book(3, "水滸傳", "施耐庵", 300.00));
array.Add(new Book(4, "紅樓夢", "曹雪芹", 400.00));
return array;
}
}
}
通過FluorineFx網站來宿主該遠程服務,通過Flex的配置文件services-config.xml配置遠程訪問的AMF連接通道。
<channels>
<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://{server.name}:{server.port}/{context.root}/Gateway.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
</properties>
</channel-definition>
</channels>
FluorineFx提供的遠程服務(RemotingService),使用Flex、Flash或Silverlight開發的客戶端都是可以訪問的,要實現客戶端的遠程調用其實是很簡單的,這里以Flex作為示例進行演示,設置通信協議為AMF3,然后直接調用當前連接到服務器端連接對象的call()方法就可以實現遠程調用,詳細請查看下面完整的Flex示例。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" fontSize="12">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.List;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
private var nc:NetConnection;
private var rs:Responder;
private function init():void
{
nc = new NetConnection();
rs = new Responder(onResult,onStatus);
nc.objectEncoding = ObjectEncoding.AMF3;
nc.connect("http://localhost:2311/FxDotNet.Web/Gateway.aspx");
nc.client = this;
}
private function onResult(result:String):void
{
this.lbServerTime.text = "服務端系統時間為:" + result;
}
private function onStatus(event:Object):void
{
trace("Error");
}
private function getServerTime(event:MouseEvent):void
{
//服務器端所提供的RemotingService的全限定名
nc.call("FxDotNet.Services.DataServices.GetServerTime",rs);
}
]]>
</mx:Script>
<mx:Button x="19" y="28" label="獲取服務器系統時間" click="getServerTime(event)"/>
<mx:Label x="19" y="60" width="402" id="lbServerTime"/>
</mx:Application>
同樣可以使用AMF來做大數據的傳輸,比如要傳遞一個集合、數組、DataTable或是DataSet等,下面以集合做為示例演示,ActionScript 3.0中新增了ArrayCollectin類,FluorineFx在服務器端對ActionScript 3.0的ArrayCollection對進行了序列化映射封裝,服務端FluorineFx.AMF3.ArrayCollection類型的對象可以直接被客戶端的ArrayCollection所接收。
如上面FluorineFx所提供的遠程服務接口中的GetBooks()方法,Flex調用此方法就會得到一個ArrayCollection對象,通過調試跟蹤返回的數據可以很清楚的分析這些數據,如下圖示:
詳細請看下面的Flex完整示例代碼:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12"
width="541" height="302" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.List;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
private var nc:NetConnection;
private var rs:Responder;
private function init():void
{
nc = new NetConnection();
rs = new Responder(onResult,onFault);
nc.objectEncoding = ObjectEncoding.AMF3;
nc.connect("http://localhost:2311/FxDotNet.Web/Gateway.aspx");
nc.client = this;
}
private function getBook(event:MouseEvent):void
{
nc.call("FxDotNet.Services.DataServices.GetBooks",rs);
}
private function onResult(result:ArrayCollection):void
{
this.bookGrid.dataProvider = result;
}
private function onFault(event:Object):void
{
trace("Error");
}
]]>
</mx:Script>
<mx:Button x="44" y="46" label="獲取圖書信息" click="getBook(event)"/>
<mx:DataGrid x="44" y="78" id="bookGrid">
<mx:columns>
<mx:DataGridColumn headerText="編號" dataField="ID"/>
<mx:DataGridColumn headerText="書名" dataField="Name"/>
<mx:DataGridColumn headerText="作者" dataField="Author"/>
<mx:DataGridColumn headerText="價格" dataField="Price"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
除了使用FluorineFx所提供的ArrayCollection外,同樣可以使用我們熟悉的Object[],List<Object>,DataTable等常用類型來作為數據返回的類型,其中Object[]和List<Object>類型的數據返回到客戶段能夠直接被客戶端所接收,如下使用Object[]作數據返回類型的代碼塊:
/*************服務端方法*************/
public Book[] GetBookArray()
{
Book[] book = new Book[]
{
new Book(1, "三國演義", "羅貫中", 100.00),
new Book(2, "西游記", "吳承恩", 200.00),
new Book(3, "水滸傳", "施耐庵", 300.00),
new Book(4, "紅樓夢", "曹雪芹", 400.00)
};
return book;
}
/*************客戶端方法*************/
private function onResult(result:Array):void
{
//
}
下面是以List<Object>類型返回的代碼示例代碼,客戶段可以使用ArrayCollection直接接收:
/*************服務端方法*************/
/// <summary>
/// 以泛型類型返回給客戶端
/// </summary>
/// <returns></returns>
public List<Book> GetBookList()
{
List<Book> list = new List<Book>
{
new Book(1, "三國演義", "羅貫中", 100.00),
new Book(2, "西游記", "吳承恩", 200.00),
new Book(3, "水滸傳", "施耐庵", 300.00),
new Book(4, "紅樓夢", "曹雪芹", 400.00)
};
return list;
}
/*************客戶端方法*************/
private function onResult(result:ArrayCollection):void
{
//
}
如果要使用DataTable類型做方法的數據返回類型就需要注意下,服務器端直接返回DataTable類型的數據客戶端是不能直接接收解析的,要使客戶斷方便解析所返回的DataTable類型數據,FluorineFx提供了DataTableTypeAttribute,為返回DataTable類型的方法加上DataTableTypeAttribute后返回給客戶端,客戶端就可以直接使用ArrayCollection接收了。
返回DataTable類型
關于FluorineFx的AMF就簡單介紹這些,要想了解更多的Flex客戶端與.NET服務器端通信,可以訪問
這里 。
本文出自 “beniao” 博客,請務必保留此出處http://beniao.blog.51cto.com/389148/166131