你带酒来,我有故事

Flex数据交互之Remoting

:: 代码生涯 二十画生 1201℃ 0评论

  一  前言

Flex数据交互常用的有三种方式:WebService、HttpService以及Remoting。

WebService方式已在这篇文章中给出,这篇文章主要讲解以Remoting方式进行数据交互,Remoting是基于AMF的数据交互,速度及性能均较WebService好,是公认最有效率的方法。

 

  二  FluorineFX

FluorineFx是一个开源库,提供了一种在.NET Framework下对Flex/Flash的远程调用过程。FluorineFx官网地址在这,FluorineFx可以在这下载

下载安装后,会在vs2008中自动增加两处模板:FluorineFx ServicesLibrary与FluorineFx ASP.NET Web Site。

         

接下来演示如何利用FluorineFx进行Flex与ASP.NET数据交互。

 

  三  ASP.NET服务器开发

(1)新建FluorineFx ServicesLibrary类库,如下图:

(2)在刚才建立的解决方案FlexRemotingDemo中,添加FluorineFx ASP.NET Web Site网站,如下图:

该网站会自动引入FlexRemotingDemo.dll:

在类库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下:运行即可看到结果:

(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

 

转载请注明:二十画生 » Flex数据交互之Remoting

喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址