zoukankan      html  css  js  c++  java
  • 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完整示例代码:

    <?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
    }

                

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

          本文示例代码下载 FluorineFxAMF.rar

  • 相关阅读:
    TRIGGERS_监测系统_多表视图触发器—向原始数据报表中插入数据
    PROCEDURE_监测系统_原始数据报表数据生成存储过程—求每天平均值插入多表视图
    PROCEDURE_监测系统_数据备份存储过程—备份原始数据,每十分钟一条,取平均值
    TRIGGERS_监测系统_原始数据表触发器—调用告警信息存储过程
    PROCEDURE_监测系统_告警信息存储过程—产生告警信息插入告警表
    秒(s) 毫秒(ms) 微秒(μs) 纳秒(ns) 皮秒(ps)及Java获得 .
    new String(byte[])和byte[]toString() 的区别
    Java 线程池 .
    加载配置文件的方式
    Spring的PropertyPlaceholderConfigurer应用
  • 原文地址:https://www.cnblogs.com/soundcode/p/3075557.html
Copyright © 2011-2022 走看看