Flex數據交互之Remoting

  一  前言

  Flex數據交互經常使用的有三種方式:WebService、HttpService以及Remoting。html

  WebService方式已在這篇文章中給出,這篇文章主要講解以Remoting方式進行數據交互,Remoting是基於AMF的數據交互,速度及性能均較WebService好,是公認最有效率的方法。json

 

  二  FluorineFX

  FluorineFx是一個開源庫,提供了一種在.NET Framework下對Flex/Flash的遠程調用過程。FluorineFx官網地址在這,FluorineFx能夠在這下載。 數組

   

  下載安裝後,會在vs2008中自動增長兩處模板:FluorineFx ServicesLibrary與FluorineFx ASP.NET Web Site。服務器

           

  接下來演示如何利用FluorineFx進行Flex與ASP.NET數據交互。ide

 

  三  ASP.NET服務器開發

  (1)新建FluorineFx ServicesLibrary類庫,以下圖:函數

  

  (2)在剛纔創建的解決方案FlexRemotingDemo中,添加FluorineFx ASP.NET Web Site網站,以下圖:性能

  

  該網站會自動引入FlexRemotingDemo.dll:flex

  

  在類庫FlexRemotingDemo的Sample.cs文件中能夠添加本身的函數:  網站

 /// <summary>
 /// 得到監測站信息(14個監測站)
 /// </summary>
 /// <returns></returns>
  public string getStationInfo()
  {
            string json = "";
            DataTable dt = new DataTable();
            dt = helper.GetStationInfo();
            if (dt != null)
            {
                json = ConverTableToJSON(dt);
            }

            return json;
     }

  將網站發佈到IIS下:運行便可看到結果:this

  

  (3)修改WEB-INF\flex下的services-config.xml配置文件:  

 <channels>
        <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
            <endpoint uri="http://localhost/FlexRemotingDemo/Gateway.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>
            <properties>
	    <!-- <legacy-collection>true</legacy-collection> -->
            </properties>
        </channel-definition>
        <!--
        <channel-definition id="my-rtmp" class="mx.messaging.channels.RTMPChannel">
            <endpoint uri="rtmp://{server.name}:2037" class="flex.messaging.endpoints.RTMPEndpoint"/>
            <properties>
                <idle-timeout-minutes>20</idle-timeout-minutes>
            </properties>
        </channel-definition>
        -->
    </channels> 

 

  四  Flex客戶端開發

  (1)新建Flex項目:

  

  (2)配置Flex項目FlexRemotingDemo:

  

  (3)編寫程序代碼:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Declarations> <mx:RemoteObject id="RO" destination="fluorine" source="ServiceLibraryDemo.Sample"> <mx:method name="getStationInfo" result="onResult(event)"/> </mx:RemoteObject> </fx:Declarations> <fx:Script> <![CDATA[ import mx.events.FlexEvent; import mx.rpc.AbstractOperation; import mx.rpc.events.ResultEvent;

       protected function btn1_clickHandler(event:MouseEvent):void { RO.getStationInfo(); } public function onResult(evt:ResultEvent):void{ txt1.text=evt.result.toString(); } ]]> </fx:Script> <s:Button id="btn1" label="得到14個監測站信息" x="630" y="50" click="btn1_clickHandler(event)"/> <s:TextArea id="txt1" x="20" y="40" width="600" />
</s:Application>

  運行結果以下:

  

 

  五  源碼下載

  源碼在這下載

 

  2013年12月12日修改

  源碼下載

 

  六  RemoteObject的封裝   

  如上面,用起來相對比較麻煩,封裝RemoteObject以方便使用,這篇文章給出了相應的封裝方法,我略做改動以適用本程序。

  (1)CYMRemoteObject.cs

package components
{
    /**
     * @author chenyuming
     */
    
    import mx.controls.Alert;
    import mx.rpc.AbstractOperation;
    import mx.rpc.AsyncToken;
    import mx.rpc.CallResponder;
    import mx.rpc.Responder;
    import mx.rpc.events.FaultEvent;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.remoting.mxml.RemoteObject;
    
    public class  CYMRemoteObject extends RemoteObject
    {
        public static const DEFAULT_DESTINATION:String = "fluorine";
        public static const DEFAULT_SOURCE:String = "";
        
        public function CYMRemoteObject(source:String,destination:String = DEFAULT_DESTINATION)
        {
            this.source = source;
            super(destination);
        }
        
        public function call(methodName:String, callback:Function, ...args):void 
        {
            var method:AbstractOperation = this.getOperation(methodName);
            
            //爲了方便起見,若是有多個參數的話就把參數包成一個Array,在J2EE端使用Object[]來獲取參數
            method.arguments = args;
            var call:AsyncToken = method.send();
            call.userDefinedCallback = callback;
            call.addResponder(new Responder(resultCallback, faultCallback));
        }
        
        public function resultCallback(event:ResultEvent):void 
        {
            var callback:Function = event.token.userDefinedCallback as Function;
            
            if (callback != null) 
            {
                var result:CYMRemoteObjectResult = new CYMRemoteObjectResult();
                result.error = false;
                result.result = event.result;
                callback(result);
            }
        }
        
        public function faultCallback(event:FaultEvent):void 
        {
            var callback:Function = event.token.userDefinedCallback as Function;
            if (callback != null) 
            {
                var result:CYMRemoteObjectResult = new CYMRemoteObjectResult();
                result.error = true;
                result.errorMessage = event.fault.toString();
                callback(result);
            }
        }
    }
}

  CYMRemoteObjectResult.cs

package components
{
    /**
     * @author chenyuming
     */
    public class CYMRemoteObjectResult
    {
        public function CYMRemoteObjectResult()
        {
            
        }
        
        public var error:Boolean = false;
        public var errorMessage:String = null;
        public var result:Object = null;
    }    
}

  (2)引用方式

protected function btn1_clickHandler(event:MouseEvent):void
{
    var ro:CYMRemoteObject = new CYMRemoteObject("ServiceLibraryDemo.Sample", "fluorine");
    ro.call("getStationInfo",onResult3);

        
    //RO.getStationInfo();
}

public function onResult3(evt:CYMRemoteObjectResult):void
{
    if(evt.error)
    {
        Alert.show(evt.errorMessage);
    }
    else
    {
        txt1.text=evt.result.toString();
    }
    
}

 

  七  返回DataTable類型

  上面利用getStationInfo返回的是json類型,有時服務器端更喜歡直接返回DataTable類型以便於直接綁定Flex中形如DataGrid的容器,下面演示數據交互類型爲DataTable:

  (1)服務器端:Sample.cs中增長函數getStationInfo2

/// <summary>
/// 得到監測站信息(14個監測站)
/// </summary>
/// <returns></returns>
public DataTable getStationInfo2()
{
    DataTable dt = new DataTable();
    dt = helper.GetStationInfo();

    return dt;
}

  (2)客戶端Flex:FlexRemotingDemo.mxml中添加DataGrid容器

<s:Button id="btn2" label="得到14個監測站信息" x="630" y="199" click="btn2_clickHandler(event)"/>
<s:DataGrid id="dg" x="20" y="199" width="600" height="401" dataProvider="{arrColl}"
            requestedRowCount="14" textAlign="center">
    <s:columns>
        <s:ArrayList>
            <s:GridColumn width="{0.21 * this.dg.width}" dataField="jcd_name" headerText="監測點名稱"></s:GridColumn>
            <s:GridColumn width="{0.13 * this.dg.width}" dataField="ssly" headerText="所屬流域"></s:GridColumn>
            <s:GridColumn width="{0.30 * this.dg.width}" dataField="zyzbytr" headerText="主要植被與土壤"></s:GridColumn>
            <s:GridColumn width="{0.10 * this.dg.width}" dataField="xqsl" headerText="小區數量"></s:GridColumn>
            <s:GridColumn width="{0.13 * this.dg.width}" dataField="fjswylz" headerText="附近水文雨量站"></s:GridColumn>
            <s:GridColumn width="{0.13 * this.dg.width}" dataField="jgsj" headerText="竣工時間"></s:GridColumn>
        </s:ArrayList>
    </s:columns>
</s:DataGrid>

  利用封裝好的RemoteObejct對象CYMRemoteObject來綁定DataGrid:

[Bindable]
private var arrColl:ArrayCollection = new ArrayCollection();

protected function btn2_clickHandler(event:MouseEvent):void
{
    var ro:CYMRemoteObject = new CYMRemoteObject("ServiceLibraryDemo.Sample","fluorine");
    ro.call("getStationInfo2",onResult2);
}

public function onResult2(evt:CYMRemoteObjectResult):void
{
    if(evt.error)
    {
        Alert.show(evt.errorMessage);
    }
    else
    {
        arrColl.removeAll();
        
        // 獲取列名
        var columnName:Array = evt.result.serverInfo.columnNames as Array;
        
        //獲取數據
        var columnData:Array = evt.result.serverInfo.initialData as Array;
        
        //列數組
        var columns:Array=new Array(); 
        
        for(var rowIndex:int = 0; rowIndex < columnData.length; rowIndex++)
        {
            var obj:Object = new Object();
            for(var colIndex:int = 0; colIndex < columnName.length; colIndex++)
            { 
                var key:String = columnName[colIndex].toString();
                var value:String = columnData[rowIndex][colIndex].toString();                        
                obj[key] = value;
            }
            
            arrColl.addItem(obj);
        }
    }

}

  運行結果:

 

  八  相關文章

  (1)Flex數據交互之WebService

相關文章
相關標籤/搜索