welcome

welcome world~~
posts - 0, comments - 0, trackbacks - 0, articles - 2
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

使用Flex Data Services 2中的RPC服务

Posted on 2008-10-23 14:55 chaichai 阅读(305) 评论(0)  编辑  收藏 所属分类: flex-study

翻译
Adobe Flex 2系列产品对开发者创建和管理面向服务的富因特网应用程序(RIAs)的方式做了几个重要改进。尽管Flex 封装(packaging)的改进使我们可以选择使用或者不使用服务器端组件来创建并部署Flex应用程序,但是Flex Data Services中的新的性能使得使用服务器端组件比任何时候都有价值。这篇文章通过着重描述Flex 1.5 和最新版本的Flex 2.0这二者的远程过程调用(remote, procedure call,RPC)之间的不同,对Flex Data Service 2中的新性能进行了概述。 Flex Data Services 2消息框架包括几个可以让RPC 服务请求变得健壮的新的服务质量(quality-of-service)特性。首先,每个信道 (channel)在发送任何请求之前都会检查它是否可以和服务器成功通讯。第二,开发者可以为每个端点(endpoint)定义多个信道,这使得配置更加灵活并在第一个信道不可用的情况下可以转到另一个。消息框架也支持集群(clustered)环境,所以RPC服务可以利用冗余的环境来提供强壮的服务。

Flex Data Services 2还提供了很多性能来提高应用程序的可维护性。一个定义服务的配置文件使开发者可以为服务添加和移除接收点(destination),配置信道端点,设置安全性来控制服务访问,为健壮的程序定义集群,以及调整日志(logging)来帮助调试。如果技术需求改变,新的配置格式也可以让开发者添加新的信道,服务,适配器(adapter),登录命令,和日志对象。

Flex 1.5通过RemoteObject, HTTPService, 和 WebService MXML标签为异步呼叫远程过程提供了三个API。这些服务称作RPC 服务而且开发者使用它们来创建有面向服务架构(service-oriented architecture,SOA)的应用程序。Flex Data Services 2在继续提供这些RPC服务的同时还引进了两个新的数据服务,这两个新的数据服务引入了新的性能和一个新的编程模型。所有的服务都基于新版本ActionScript(ActionScript 3.0)提供的一个公共消息体系。这篇文档描述了Flex 1.5和Flex 2之间的不同以及Flex Data Services 2中的RPC服务是如何利用这些改进的。


RPC服务和消息体系
Flex 2中新的消息体系为RPC服务引进了几个新的概念。这一节从较高层次阐明了它与Flex 1.5的不同并且概要说明了Flex 2中与之等价的特性。

在Flex 1.5中,开发者使用MXML标签来连接RPC服务。你可以指定几个属性,比如服务名,请求将要被发送到的端点等等。Flex 1.5中的各个RPC服务使用了不同的技术,所以每个服务的配置选项和术语都不一样。例如,一个RemoteObject标签指定了命名的或未命名的源(source)并连接到一个Action Message Format(Action消息格式,AMF)网关,而HTTPService和WebService标签则使用命名的服务或原始的URL并使用基于文本的查询参数或XML连接到一个HTTP Proxy。

Flex 2为这个模型引入了几个改进,使该模型在不同的信道之间更加一致,而且为开发者提供了更高的灵活性。在客户端,开发者可以使用MXML标签或纯ActionScript API来声明服务连接。如果连接只是在客户端,服务的URI会被指定为一个参数。如果连接利用了Flex Data Services,开发者就定义一个关联到所需服务的逻辑接收点(destination)。这些服务表现出各种各样截然不同的性能,比如间接web service呼叫和消息集成。在服务器端,所有的接收点都通过配置文件被配置好了。一个接收点包括了接收点所连接的端点的信息,所有连接都会使用的多种消息选项,以及用来通讯的信道。信道展现了一个通讯机制,比较有代表性地就是指定协议和一些诸如信道是否使用轮询(polling)和预期的轮询间隔之类的选项。

这些各种各样的服务提供的所有通讯都经由一个将消息传递给适当的服务的公共消息代理。消息类型和选中的接收点(destination)被消息代理用来选择适当的服务并确保该服务可以处理这个消息。RemoteObject消息被发送到RemotingService,而HTTPService和WebService消息被发送到ProxyService。表 1 把Flex 1.5的服务概念和Flex Data Services 2中与之等价的东西做了比较。

表 1. Flex 1.5和 Flex Data Services 2 概念的比较

Flex 1.5 Services概念
Flex Data Services 2 中的等价物

命名的和未命名的服务(Named and Unnamed Services)

在Flex1.5中,鼓励开发者赋予服务一个名字来作为别名;但是,客户端也可以通过未命名的方式动态地提供一个服务的细节(比如一个第三方URL,或是一个对象的源文件)
接收点(Destinations)

一个接收点等同于Flex1.5中的一个命名的服务。接收点是指最终的端点。所有的请求必须被发送到相关服务(Remoting Service, Proxy Service, Message Service, 和Data Service)的一个接收点。

Proxy

典型地,HTTPService和WebService请求的预期端点是一个远程的第三方服务。但是,Flash? Player的安全沙盒(sandbox)把请求约束在程序加载的域中。为了避免在每一个远程站点都需要一个crossdomain.xml文件,Flex 1.5向开发者提供了一个内部的Proxy Servlet来把请求发送到合适的端点。
Proxy Service

尽管HTTPService和WebService使用消息代理在Proxy Service中回复请求,安全沙盒(sandbox)限制仍然被应用到所有服务。 Prox Service不再被默认使用;useProxy属性的默认值是false。由于useProxy的值是false,消息代理并没有联系而且destination属性也没有用到。作为替代的是,开发者必须为HTTPService标签设置url属性或为WebService标签定义wsdl属性。开发者通过选取一个特定的直接信道来把不是基于消息的请求发送到第三方端点。 为了使用proxy,开发者必须在HTTPService或WebService中设定useProxy为true。在HTTPService或WebService中设定接收点就会自动把useProxy设置为true。使用ProxyService的时候,可以对任何信道发送请求。信道被注册为消息代理的端点。基于HTTP的信道发送消息到一个消息代理servlet。基于实时消息协议(RTMP)的信道发送消息来指定TCP/IP端口;消息代理管理监听这些端口的socket。

AMF 网关

RemoteObject请求的端点是一个AMF网关servlet
Remoting Service

没有为RemoteObject指定信道;可以通过任何信道向Remoting Service发送请求。


RPC服务配置
在Flex 1.5中,编译器和运行时服务的配置设置都在同一个配置文件,flex-config.xml中。这个配置文件有三个部分用于RPC服务:<remote-objects>用于RemoteObject标签,<web-service-proxy>用于WebService标签,<http-service-proxy>用于HTTPService标签。Flex在编译时使用这些服务配置信息来为MXML标签生成代码并验证标签属性。下面的例子展示了Flex 1.5配置文件,flex-config.xml的结构。


切换行号显示
    1 <flex-config>
    2    <debugging />
    3    <compiler />
    4    <cache />
    5    <flash-player />
    6    <web-service-proxy />
    7    <http-service-proxy />
    8    <remote-objects />
    9    <logging />
   10    <fonts />
   11 </flex-config>
Flex 1.5 AMF网关也有自己的配置文件,gatewag-config.xml。开发者通过使用这个文件可以自定义一些特性,包括传输RemoteObject请求的服务适配器和为自定义服务安全性设定的登录命令。接下来的代码片断展示了Flex 1.5 RemoteObject配置文件,gateway-config.xml的结构。


切换行号显示
    1 <gateway-config>
    2    <service-adapters />
    3    <logger />
    4    <security />
    5    <serialization />
    6    <translator />
    7    <redirect-url />
    8    <lowercase-keys />
    9    </gateway-config>
在Flex Data Services 2中的一个分离的配置文件,services-config.xml中,包含了服务特有的配置。Flex 1.5中的三个与服务相关的部分在flex-config.xml中被清除了。但是,编译器特有的配置仍然在这个文件中。其他的web层的配置设定,象缓存和Flash Player检测,都在flex-server-config.xml文件中。Flex 1.5中的gateway-config.xml不再被使用。一个新的,公共的services-config.xml文件包含了所有与网关相关的特性并把这些设定应用到了所有的服务。

这个service-config.xml配置文件可以让开发者包含来自外部文件的单个服务定义。这有助于分离服务特定的接收点并减小了主要服务配置文件的大小,使我们可以快速访问公共的部分,比如安全,信道,和日志设定。下面的例子通过在分离的包含文件中定义各个服务,展示了Flex Data Services 2配置文件,services-config.xml的一般结构。


切换行号显示
    1 <services-config>
    2    <services>
    3      <service-include file-path="remoting-service.xml" />
    4      <service-include file-path="proxy-service.xml" />
    5    </services>
    6    <security />
    7    <channels />
    8    <clusters />
    9    <logging />
   10    <system />
   11 </services-config>
如果Flex应用程序使用了Flex Data Services,那么在编译时就需要这个services-config.xml配置文件。在使用RPC服务的情况下,这些配置会被应用到所有使用RemoteObject、基于proxy的WebService或HTTPService的应用程序。

Mxmlc编译器可以通过使用flex-config.xml文件或命令行切换来指向这个服务配置文件。服务配置信息在编译时是必需的,因为生成的代码必须向客户端说明哪些信道可以被各个服务接收点使用。下面的配置代码片断通过使用flex-config使mxmlc编译器指向了Flex Data Services 2配置文件。


切换行号显示
    1 <flex-config>
    2    <compiler>
    3      <services>
    4        services-config.xml
    5      </services>
    6      ...
    7    </compiler>
    8 </services-config>
下面的配置代码片断通过使用命令行使mxmlc编译器指向了一个Flex Data Services 2配置文件:


切换行号显示
    1 mxmlc --load-config=flex-config.xml --services=services-config.xml MyApp.mxml
表 2展示了Flex 1.5和 Flex Data Services 2配置之间的不同。


Flex 1.5 和 Flex Data Services2配置之间的不同
Flex 1.5 服务配置

Gateway URL 和 Proxy URL

使用 flex-config.xml:


切换行号显示
    1 HTTPService, WebService
    2 {context.root}/flashproxy
    3 RemoteObject
使用mxmlc命令行切换:


切换行号显示
    1 HTTPService, WebService
    2 -proxyurl=/myapp/flashproxy
    3 RemoteObject
    4 -gatewayurl=/myapp/amfgateway
Flex Data Services 2服务配置

信道

服务使用任意多个信道端点来传输消息。针对服务的端点设置不是必需的;替代的做法是开发者创建新的信道。信道必需在服务配置文件,service-config.xml中定义。信道被服务自主地定义:


切换行号显示
    1 <channel-definition id="my-amf" ...>
    2    <endpoint uri="http://www.abc.com/messagebroker/amf" ... />
    3 </channel-definition>
一个默认信道集合可以被制定用于一个服务:


切换行号显示
    1   <service id="remoting-service" ...>
    2     ...
    3     <default-channels>
    4       <channel ref="my-amf"/>
    5     </default-channels>
    6     ...
    7   </service>
一个接收点也可以指定自己的信道列表来覆写(override)服务默认的信道:


切换行号显示
    1   <destination id="MyManager">
    2     <channels>
    3       <channel ref="my-amf"/>
    4     </channels>
    5     ...
    6   </destination>
单独的信道不能在命令行中被指定;但是,一个mxmlc命令行切换可以将编译器指向完整的服务配置文件:


切换行号显示
    1     --services=/flex/services-config.xml
Flex 1.5服务配置

服务白名单(whitelist)

一个白名单被用来限制哪些服务对客户端可用。

HTTPService和WebService服务可以在基于最终的第三方端点URL的白名单中被指定。


切换行号显示
    1   <whitelist>
    2     <unnamed>
    3       <url>
    4        http://www1.abc.com/*
    5       </url>
    6       <url>
    7        https://www1.abc.com/*
    8       </url>
    9     </unnamed>
   10     <named>
   11       <service name="MyManager">
   12         <url>
   13          http://www.abc.com/mysvc/10/
   14         </url>
   15       </service>
   16     </named>
   17   </whitelist>
RemoteObject对象可以在基于远程对象源文件的白名单中被指定。


切换行号显示
    1   <whitelist>
    2     <unnamed>
    3       <source>*</source>
    4     </unnamed>
    5     <named>
    6       <object name="WeatherService">
    7         <source>
    8           samples.WeatherService
    9         </source>
   10         <type>stateless-class</type>
   11       </object>
   12     </named>
   13   </whitelist>
Flex Data Services 2服务配置

服务接收点

向一个服务添加一个接收点等价于向一个白名单中添加某些东西。

Proxy Service接收点可以指定url模式和soap端点来提供与Flex 1.5中未命名服务等价的功能。服务的默认URL在url属性中被定义。动态或者客户端提供的URL在dynamic-url属性中被定义。


切换行号显示
    1   <destination id="flickr">
    2     <properties>
    3       <url>
    4        http://www.abc.com/mysvc/10/
    5       </url>
    6       <dynamic-url>
    7        http://www1.abc.com/*
    8       </dynamic-url>
    9       <dynamic-url>
   10        https://www1.abc.com/*
   11       </dynamic-url>
   12     </properties>
   13   </destination>
注意有两个接收点,defaultHttp和defaultHttps,对Proxy Service已经配置,允许开发者在不指定接收点的情况下使用HTTPService和WebService标签。但是,必须使用defaultHttp为基于HTTP的URL的默认接收点配置dynamic-url,对基于HTTPS的URL则使用defaultHttps来配置。

使用了JAVA 适配器的Remoting Service接收点不再允许在客户端指定源文件。开发者必需为服务器上的每个JAVA源文件注册一个唯一的接收点。


切换行号显示
    1   <destination id="WeatherService">
    2     <properties>
    3       <source>
    4         samples.WeatherService
    5       </source>
    6       <stateful>false</stateful>
    7     </properties>
    8   </destination>
Flex 1.5服务配置

Proxy 和 AMF Gateway 日志

在Flex 1.5中,开发者可以通过修改服务器端gateway-config.xml文件中的日志设置来调试AMF请求。Proxy请求可以通过修改web层编译器使用的flex-config.xml文件中的日志设置来调试。 Flex Data Services 2 服务配置 日志 消息代理对所有的服务都有一个统一的日志系统。services-config.xml中的日志设置部分让开发者可以自定义日志级别并对特殊类别限制信息。

Flex 1.5服务配置

客户端日志

在Flex1.5中开发者可以通过把flex-config.xml有关调试部分中的http-service-proxy-debug,web-service-proxy-debug,或 remote-object-debug设为true来在客户端调试服务请求。开发者可以通过使用Flex Builder? Network Monitor,Flash Remoting NetConnection Debugger,和调试版的Flash Player输出到用户目录下flashlog.txt文件中的跟踪信息来查看客户端的日志信息, Flex Data Services 2 服务配置 客户端日志API和日志目标(Log Targets) Flex 2中的mx.logging包中包含了一个新的客户端日志库。所有服务都使用这个客户端日志API来汇报信息。开发者可以指定日志时间的等级并过滤事件类别。开发者可以激活一个日志目标来查看一个特定位置的信息。最经常用的目标就是TraceTarget(在mx.logging.targets包中),它使用trace()函数来汇报信息。调试版本的Flash Player把跟踪信息输出到用户目录下的flashlog.txt文件中。


RPC服务MXML API的改动
Flex2中的RPC服务API本质上来说和Flex 1.5是一样的。但是,到公共消息体系的过渡影响了少数与服务通讯和命名有关的属性。表3概括了Flex Data Services 2对Flex 1.5的MXML API的改动。

表 3. Flex Data Services 2对Flex 1.5的MXML API的改动概况

Flex 1.5 MXML API
Flex Data Services 2 MXML API

mx:RemoteObject

source属性与未命名的远程对象一起使用。它为一个RemoteObject定义了一个动态源名字,没有在白名单配置中注册一个命名的对象

named属性与命名的远程对象一起使用。它为一个注册的对象源提供了一个别名。

protocol属性定义了当连接AMF网关时HTTP或HTTPS是否会被使用。

endpoint属性允许开发者为一个AMF网关指定一个自定义位置。
mx:RemoteObject

source属性被Remoting Service Java适配器忽略。ColdFusion在CFC适配器中支持客户端指定的源。

named属性不赞成使用,应该使用destination属性。

不支持protocol属性。用来连接消息代理的协议取决于为接收点选取的信道。

endpoint属性不可用。

mx:WebService
mx:HTTPService

protocol属性决定了当连接proxy或第三方端点时是否要使用HTTP或HTTPS。

serviceName属性和命名的使用了proxy的web服务一起使用。

任意服务

开发者可以把WebService、RemoteObject 操作或HTTPService呼叫的result属性绑定到一个服务返回的最终结果。
mx:WebService
mx:HTTPService

不支持protocol属性。用来连接消息代理的协议取决于为接收点选取的信道。

serviceName属性不赞成使用,应该使用destination属性。

任意RPC服务

为了避免和可以让开发者指定一个结果处理器的MXML 结果事件属性冲突,WebService、RemoteObject 操作或HTTPService呼叫的result属性被重命名为lastResult。


使用RPC服务中的信道
一个信道可以对从客户端传输一个消息到消息代理的终端进行响应。用来传输消息的协议被指定到该信道。一个信道必须也能支持客户端的数据类型,即在Flex程序中使用的使用了ActionScript 3.0的类型。一个信道包括一个对序列化(serialize)请求和反序列化(deserialize)响应的客户端实现,和一个端点处对反序列化请求和序列化响应的服务器端实现。Flex Data Services 2装载了几个信道来支持基于服务的应用程序的各种各样的需求。

AMF 信道:AMF是一个用来有效地序列化ActionScript对象的一个二进制消息格式。AMFChannel为Flash Player使用了flash.net.NetConnection类来通过HTTP异步地发送AMF格式的消息到AMFEndpoint。Flash Player 8.0引进了AMF的一个新版本:AMF 3来协同新的ActionScript 3.0语言,尽管仍然支持先前的版本,AMF 0。除了支持新的ActionScript 3.0数据类型之外,AMF 3还使用了一个更简洁的编码格式并且对经常使用的类描述和字符串使用引用进行序列化来减少冗余信息。NetConnection(并且因此AMFChannel)默认使用AMF 3。在允许通过HTTP使用二进制信息并且不需要为了安全性而加密的环境中,AMFChannel对所有RPC服务都是被推荐使用的信道。

安全AMF信道:除了使用HTTPS向AMFEndpoint发送AMF格式的消息之外,这个信道与AMFChannel是相同的。
RTMP信道:RTMP也使用AMF来序列化ActionScript对象;但是,它与RTMPEndpoint维持一个持久的的连接并允许实时的通讯。由于RPC服务是以单个客户端/服务器请求/响应模型异步生成的,所以实时通讯并不是必需的。

HTTP信道:这是一个基于文本的信道,它通过HTTP使用flash.net.URLLoader来异步发送XML格式信息到HTTPEndpoint。XML格式支持强类型的ActionScript 3.0数据并且包含许多AMF 3的优化,比如对经常使用的对象通过引用序列化,类的定义,以及字符串。这个信道在只需要文本通讯的环境下是很有用的。
注意:HTTPChannel并不完全支持flash.utils.Iexternalizable;所以,在使用这个信道的时候,需要恢复对象引用的mx.utils.ObjectProxy 和 mx.collections.ArrayCollection的实例不能被序列化。

安全HTTP信道——除了使用HTTPS向HTTPEndpoint发送信息外,该信道和HTTPChannel是一样的。

ActionScript 3.0数据类型和序列化
Flex 2 和 ActionScript 3.0在Flex程序中引入了一些新的数据类型,在开发者使用RemoteObject 和 Remoting Service的时候应该考虑到这些新类型。


XML
ActionScript 3.0包含了一个新的内置的XML数据类型,它支持E4X语法。开发者被孤立使用这个强大并且有用的API。在flash.xml包中的从ActionScript 2继承的XMLDocument 和 XMLNode类依然可用。客户端的XML和flash.xml.XMLDocument实例都会被消息端点作为Java org.w3c.dom.Document实例进行反序列化。服务器端的org.w3c.dom.Document会被客户端作为新的XML类型的实例进行反序列化。所以,开发者要意识到对于那些发送到服务器端又返回的对象,任何flash.xml.XMLDocument类型的数据都会被作为XML返回。


强类型的对象
在Flex 1.5中,用户使用Object.registerClass来映射自定义的客户端和服务器端的数据类型。在ActionScript 3.0中,这个函数被改为flash.net.registerClassAlias。这个API为一个客户端类注册了一个别名,当这个类的实例被序列化的时候会包含这个别名。如果没有注册别名,那么一个实例就会被作为一个匿名对象发送。使用别名还使客户段可以将客户端的类映射到服务器端的一个不同名的类,尽管为了最佳实践开发者应该使用相同的名字来避免混淆。一个客户端类的别名必须在该类的实例被发送到服务器或从客户端接收之前注册,以便它们都可以被正确地反序列化。

Flex 2 MXML编译器包含了几个优化,比如类的延迟初始化(lazy-initialization)和基于依存关系(dependency-based)的连接程序。这样一来,对registerClassAlias的呼叫就必须在所有数据请求设定之前,而且对客户端类的依存关系必须写在代码中来保证它们被连接到已编译的程序。为了让这个过程更简单,mxmlc编译器包含了对特定[RemoteClass]元数据标签的支持来确保一个类在RPC服务中使用的时候已经就绪。下面的ActionScript 3.0 的代码片断在Flex程序中映射了远程类。


切换行号显示
    1     package com.mycompany
    2     {   
    3       [RemoteClass(alias="com.mycompany.Employee")]
    4       public class Employee
    5       {
    6         …
    7       }   
    8     }

Number, int, 和 uint
除了双精度浮点型的Number类型以外,ActionScript 3.0还引入了两个新的整型,int(有符号整数)和uint(无符号整数)。新的ActionScript虚拟机(AVM+)把整数作为不定长的29位编码的整型来存储;较大的整数值用Number来存储。在服务器端使用java.lang.Integer对int 和 uint型进行反序列化。Number在服务器端仍然被反序列化为java.lang.Double。因为当调用方法和构造强类型实例的时候,Remoting Service中的Java adapter使用松散的类型编组规则,所以所有的数都会被正确地转换成用户API所需要的类型。


自定义序列化和flash.utils.Iexternalizable
ActionScript 3.0包含一个新的接口,可以让开发者控制他们自己的强类型的类的序列化。实现了flash.utils.Iexternalizable接口的实例依照readExternal 和 writeExternal方法的实现来进行序列化。客户端类必须有一个注册的别名,而且相应的服务器端的类必须可以反序列化这个类的实例。因为这个类型的序列化格式是完全自定义的,所以服务器端的类必须可以被正确地序列化。


数据绑定和MXML组件
为了让服务可以作为data provider在Flex 2组件中使用,数据类型必须分派正确的事件来支持数据绑定和事件传播的更改。为此,Flex 2就对数据类型序列化规则做了一些改变来使数据绑定更加容易。


<mx:Model/>
一个MXML Model标签使一般的对象属性可以用在数据绑定中。一个Model标签对应一个ActionScript类型,mx.utils.ObjectProxy,它在服务器端被作为java.util.HashMap进行反序列化。

注意:mx.utils.ObjectProxy类实现了 flash.utils.Iexternalizable,所以HTTPChannel类不完全支持这个类型——其他类型和Iexternalizable类型的内容之间的对象引用不会被保存。


mx.collections.ArrayCollection
集合(collections)在Flex 2中被广泛地应用。它们为数组提供了一个事件框架来分派正确的事件,这样一来对集合结构所做的更改就能反应在Flex组件(特别是UI组件)上,反过来也是一样。Flex Data Services 现在把客户端的mx.collections.ArrayCollection实例映射为服务器端的java.util.ArrayList,而服务器端的java.util.Collection则被映射为客户端的mx.collections.ArrayCollection。如果一个本地客户端数组需要服务器端的响应,那么服务器将返回一个本地的JAVA数组(比如,java.lang.Object[])。同时需要注意的是,客户端的ActionScript数组在服务器端被作为本地java.lang.Object[]数组进行反序列化。

注意:mx.utils.ObjectProxy类实现了 flash.utils.Iexternalizable,所以HTTPChannel类不完全支持这个类型——其他类型和Iexternalizable类型的内容之间的对象引用不会被保存。


只有注册用户登录后才能发表评论。


网站导航: