Flex与.NET互操作(十四):FluorineFx的AMF协议通信

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 {  getset; }
         public  string Name {  getset; }
         public  string Author {  getset; }
         public  double Price {  getset; }

         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与.NET互操作(十四):FluorineFx的AMF协议通信

 

      详细请看下面的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接收了。

 


/******************服务端方法***********************/
[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
}

 

            Flex与.NET互操作(十四):FluorineFx的AMF协议通信

      关于FluorineFx的AMF就简单介绍这些,要想了解更多的Flex客户端与.NET服务器端通信,可以访问 这里 。 

      本文示例代码下载 FluorineFxAMF.rar

你可能感兴趣的:(.net)