Flex與.NET互操作(十四):FluorineFx的AMF(Action Message Format)協(xié)議通信
Flex與.NET互操作(十四):FluorineFx的AMF(Action Message Format)協(xié)議通信
標(biāo)簽:AMF,FluorineFx
原創(chuàng)作品,允許轉(zhuǎn)載,轉(zhuǎn)載時(shí)請務(wù)必以超鏈接形式標(biāo)明文章 原始出處 、作者信息和本聲明。否則將追究法律責(zé)任。http://beniao.blog.51cto.com/389148/166131
AMF(Action Message Format)在開發(fā)Flash/Flex應(yīng)用中使用頻率是非常高的,相對普通的HTTP、WebService的SOAP等多種數(shù)據(jù)通信方式的效率更高,有人曾經(jīng)做過這方面的測試,詳細(xì)可以訪問:http://xinsync.xju.edu.cn/index.php/archives/2162。本文將結(jié)合FluorineFx來提供通信服務(wù)接口,在客戶端通過Flex來訪問,簡單的介紹下關(guān)于使用FluorineFx的AMF(Action Message Format)協(xié)議通信的用法。
通過FluorineFx網(wǎng)站來宿主該遠(yuǎn)程服務(wù),通過Flex的配置文件services-config.xml配置遠(yuǎn)程訪問的AMF連接通道。
返回DataTable類型
首先建立一個FluorineFx服務(wù)庫,并建立一個數(shù)據(jù)傳輸對象(DTO),為該對象添加[FluorineFx.TransferObject]表示該對象可以用作于FluorineFx的數(shù)據(jù)傳輸對象,這個對象將會在本文后面用到,如下代碼塊:
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.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的遠(yuǎn)程服務(wù)(即標(biāo)記有[RemotingService]的對象),通過該服務(wù)提供對外訪問的方法接口,如下代碼塊:
namespace FxDotNet.Services
{
[RemotingService]
public class DataServices
{
public DataServices()
{
}
/// <summary>
/// 獲取服務(wù)端的系統(tǒng)時(shí)間
/// </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;
}
}
}
{
[RemotingService]
public class DataServices
{
public DataServices()
{
}
/// <summary>
/// 獲取服務(wù)端的系統(tǒng)時(shí)間
/// </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網(wǎng)站來宿主該遠(yuǎn)程服務(wù),通過Flex的配置文件services-config.xml配置遠(yuǎn)程訪問的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>
<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提供的遠(yuǎn)程服務(wù)(RemotingService),使用Flex、Flash或Silverlight開發(fā)的客戶端都是可以訪問的,要實(shí)現(xiàn)客戶端的遠(yuǎn)程調(diào)用其實(shí)是很簡單的,這里以Flex作為示例進(jìn)行演示,設(shè)置通信協(xié)議為AMF3,然后直接調(diào)用當(dāng)前連接到服務(wù)器端連接對象的call()方法就可以實(shí)現(xiàn)遠(yuǎn)程調(diào)用,詳細(xì)請查看下面完整的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 = "服務(wù)端系統(tǒng)時(shí)間為:" + result;
}
private function onStatus(event:Object):void
{
trace("Error");
}
private function getServerTime(event:MouseEvent):void
{
//服務(wù)器端所提供的RemotingService的全限定名
nc.call("FxDotNet.Services.DataServices.GetServerTime",rs);
}
]]>
</mx:Script>
<mx:Button x="19" y="28" label="獲取服務(wù)器系統(tǒng)時(shí)間" click="getServerTime(event)"/>
<mx:Label x="19" y="60" width="402" id="lbServerTime"/>
</mx:Application>
<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 = "服務(wù)端系統(tǒng)時(shí)間為:" + result;
}
private function onStatus(event:Object):void
{
trace("Error");
}
private function getServerTime(event:MouseEvent):void
{
//服務(wù)器端所提供的RemotingService的全限定名
nc.call("FxDotNet.Services.DataServices.GetServerTime",rs);
}
]]>
</mx:Script>
<mx:Button x="19" y="28" label="獲取服務(wù)器系統(tǒng)時(shí)間" click="getServerTime(event)"/>
<mx:Label x="19" y="60" width="402" id="lbServerTime"/>
</mx:Application>
同樣可以使用AMF來做大數(shù)據(jù)的傳輸,比如要傳遞一個集合、數(shù)組、DataTable或是DataSet等,下面以集合做為示例演示,ActionScript 3.0中新增了ArrayCollectin類,F(xiàn)luorineFx在服務(wù)器端對ActionScript 3.0的ArrayCollection對進(jìn)行了序列化映射封裝,服務(wù)端FluorineFx.AMF3.ArrayCollection類型的對象可以直接被客戶端的ArrayCollection所接收。
如上面FluorineFx所提供的遠(yuǎn)程服務(wù)接口中的GetBooks()方法,F(xiàn)lex調(diào)用此方法就會得到一個ArrayCollection對象,通過調(diào)試跟蹤返回的數(shù)據(jù)可以很清楚的分析這些數(shù)據(jù),如下圖示:

詳細(xì)請看下面的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="價(jià)格" dataField="Price"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
<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="價(jià)格" dataField="Price"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
除了使用FluorineFx所提供的ArrayCollection外,同樣可以使用我們熟悉的Object[],List<Object>,DataTable等常用類型來作為數(shù)據(jù)返回的類型,其中Object[]和List<Object>類型的數(shù)據(jù)返回到客戶段能夠直接被客戶端所接收,如下使用Object[]作數(shù)據(jù)返回類型的代碼塊:
/*************服務(wù)端方法*************/
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
{
//
}
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直接接收:
/*************服務(wù)端方法*************/
/// <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
{
//
}
/// <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類型做方法的數(shù)據(jù)返回類型就需要注意下,服務(wù)器端直接返回DataTable類型的數(shù)據(jù)客戶端是不能直接接收解析的,要使客戶斷方便解析所返回的DataTable類型數(shù)據(jù),F(xiàn)luorineFx提供了DataTableTypeAttribute,為返回DataTable類型的方法加上DataTableTypeAttribute后返回給客戶端,客戶端就可以直接使用ArrayCollection接收了。


關(guān)于FluorineFx的AMF就簡單介紹這些,要想了解更多的Flex客戶端與.NET服務(wù)器端通信,可以訪問 這里 。
本文示例代碼下載 FluorineFxAMF.rar
本文出自 “beniao” 博客,請務(wù)必保留此出處http://beniao.blog.51cto.com/389148/166131
posted on 2010-11-19 10:04 aiaiwoo 閱讀(353) 評論(0) 編輯 收藏 所屬分類: AC3/FLEX