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类型
/* *****************服务端方法********************** */ [DataTableType(" Book " , " FxDotNet.Services.DTO.Book " )] public DataTable GetBookTable() { DataTable dt = new DataTable( " Book " ); dt.Columns.Add( " ID " , typeof ( int )); dt.Columns.Add( " Name " , typeof ( string )); dt.Columns.Add( " Author " , typeof ( string )); dt.Columns.Add( " Price " , typeof ( double )); DataRow dr = dt.NewRow(); dr[ " ID " ] = 1 ; dr[ " Name " ] = " 《三国演义》 " ; dr[ " Author " ] = " 罗贯中 " ; dr[ " Price " ] = 100.00 ; dt.Rows.Add(dr); dr = dt.NewRow(); dr[ " ID " ] = 2 ; dr[ " Name " ] = " 《西游记》 " ; dr[ " Author " ] = " 吴承恩 " ; dr[ " Price " ] = 200.00 ; dt.Rows.Add(dr); dr = dt.NewRow(); dr[ " ID " ] = 3 ; dr[ " Name " ] = " 《水浒传》 " ; dr[ " Author " ] = " 施耐庵 " ; dr[ " Price " ] = 300.00 ; dt.Rows.Add(dr); dr = dt.NewRow(); dr[ " ID " ] = 4 ; dr[ " Name " ] = " 《红楼梦》 " ; dr[ " Author " ] = " 曹雪芹 " ; dr[ " Price " ] = 400.00 ; dt.Rows.Add(dr); return dt; } /* *****************客户端方法********************** */ private function onResult(result:ArrayCollection): void { // do other }
关于FluorineFx的AMF就简单介绍这些,要想了解更多的Flex客户端与.NET服务器端通信,可以访问 这里 。
本文示例代码下载 FluorineFxAMF.rar
版权说明
本文属原创文章,欢迎转载,其版权归作者和博客园共有。
作 者:Beniao
文章出处:http://beniao.cnblogs.com/ 或 http://www.cnblogs.com/