加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

flex java通信协议

发布时间:2020-12-15 01:39:58 所属栏目:百科 来源:网络整理
导读:如何将 Flex 和 Spring 进行集成,使 Flex 前端能够与 Java EE 后端进行通信? Flex 通过远程方法调用和实时通信技术实现异步通信,Flex 的通信协议主要有三种:HttpService、WebService 和 RemoteObject。RomoteObject 协议作为 Flex 提供的最快的通信方式

如何将 Flex 和 Spring 进行集成,使 Flex 前端能够与 Java EE 后端进行通信? Flex 通过远程方法调用和实时通信技术实现异步通信,Flex 的通信协议主要有三种:HttpService、WebService 和 RemoteObject。RomoteObject 协议作为 Flex 提供的最快的通信方式,通过集成 BlazeDS,利用 AMF(Action Message Format)二进制协议使得 Flex 前端能轻松与 Java EE 后端进行数据交互,它是 Flex 集成 Spring 的首选通信协议。 ??? BlazeDS 是 Adobe Live-Cycle Service 的免费开源版本,它使用 AMF 二进制协议通过 AMF 管道构建了 Flex 和 Spring 进行数据通信的桥梁。BlazeDS 可以实现 Flex 对 Java 对象的远程调用。BlazeDS 可以部署运行在大多数 Web 应用服务器上,如 Tomcat、Websphere、JBoss 以及 Weblogic。 ??? 提到通信就得面临两个问题,一是通信协议的选择,二是数据协议的定义。通信协议耳熟能详的就有好几种,TCP,UDP,HTTP,FTP等等。数据协议是一种数据交换的格式,像jason,xml,amf3,google protocol都可以用作数据协议,你也可以自己根据通信的效率,安全等因素来定义自己的数据协议。   通信系统的开发是一项很复杂的工作,不要以为往发服务端发一个Hello World!就认为完全掌握了通信系统的开发。概括来说要开发一个健壮的通信系统,必须从这几个方面来着手。   一,通信粘包的处理   这里包的概念是逻辑上的数据包,也就是我们发送的一个完整业务消息包,粘包情况有两种,一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包。不是所有的粘包现象都需要处理,若传输的数据为不带结构的连续流数据(如文件传输),则不必把粘连的包分开(简称分包)。但在实际工程应用中,传输的数据一般为带结构的数据,这时就需要做分包处理。   为了避免粘包现象,可采取以下几种措施。一是对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令 push,TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;二是对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;三是由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。   以上提到的三种措施,都有其不足之处。总的来说降低了通信系统的吞吐量。我们可以自己设计一个分包算法来处理粘包的问题,该算法的实现是这样的: 1. 当有数据到达时,将数据压入程序缓冲区。 2. 循环处理缓冲区,如果缓冲区长度大于包头长度,则取出长度信息n,否则跳出循环,如果缓冲区的长度大于n,则从缓冲区取出一个完整包进行处理,否则跳出循环。 如果你是Java的爱好都可以参考一下Mina和netty2的实现,像Mina和Netty2都提供了粘包处理类可供使用,像Mina的CumulativeProtocolDecoder类,Netty2的LengthFieldBasedFrameDecoder。   二,数据协议选择   现在已经有很多数据协议可供我们选择,像jason,google protocol等等,这些协议相应的语言都有API来对自身数据做协议处理,我们选择协标准无非就是效率和大小,这里每个人可以根据实际的应用环境选择适合的数据协议。   三,网络系统的安全性   网络安全是一个永远的话题,对通信数据加密一般常RSA对byte流加密,FLOOD验证,IP黑名单验证都是必须考虑到的。   以上是做网络开发必须了解的一些基础知识,在这里我们使用一个具体的实例来加深一下理解,Java与Flex使用AMF3数据协议通信。做过网络开发的一般都会知道套接字(SOCKET),很多语言都会通SOCKET来提供对网络操作的API,Java的提供的NIO SOCKET是一个高效的异步通信API,当然可以在这个基础上来开发我们的网络应用,但这种Native API需要我们花很多精力来处理网络通信的细节,消弱了我们对业务的关心。为我们开发带来很多不便性,幸好Java有很多现成的NIO SOCKET框架可供使用,像Mina,Netty2,xSocket等等,这些框架处理了很多底层的通信问题,提供了一些易用的API以供使用。在这个实例中我们使用Netty2来做通信框架。   定义消息包,消息包有定长包和不定长包,不定长包无非就是要在消息包中加入长度信息,以对收到的网络字节流进行分界。消息包的定义如下 : 4.1.1?? 确定Flex客户端系统和Java服务器端通信框架(1) 开发异构系统时,如何进行通信和传递数据是我们比较关注的问题。使用Flex+Java开发基于B/S结构企业应用,客户端和服务器端的通信协议是我们所熟知的HTTP协议。在Flex中,基于HTTP协议访问服务器的通信组件有三个: HttpService(mx.rpc.http.mxml.HTTPService) WebService(mx.rpc.soap.mxml.WebService) RemoteObject(mx.rpc.remoting.mxml.RemoteObject) HttpService组件可以调用很多不同技术的服务端页面,比如JSP、ASP、PHP、Java Servlet、ColdFusion Page等。在大多数情况下,使用HttpService访问服务器端页面来完成Flex客户端与服务器端的数据交互,服务器端返回的结果一般都是XML 格式的数据。下面是Adobe官方关于HTTPService组件的例子应用: ?? 1. <?xml version="1.0" encoding="utf-8"?> ?? 2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" ?? 3.??? creationComplete="feedRequest.send()" layout="absolute"> ?? 4.??? <mx:HTTPService id="feedRequest" ?? 5.?????? url="http://weblogs.macromedia.com/mchotin/index.xml" ?? 6.?????? useProxy="false" /> ?? 7.??? <mx:Panel x="10" y="10" width="475" height="400" ?? 8.???????? title="{feedRequest.lastResult.rss.channel.title}"> ?? 9.??????? <mx:DataGrid id="dgPosts" x="20" y="20" width="400" ? 10.??????????? dataProvider="{feedRequest.lastResult.rss.channel.item}"> ? 11.??????????? <mx:columns> ? 12.?????????????? <mx:DataGridColumn headerText="Posts" dataField="title"/> ? 13.?????????????? <mx:DataGridColumn headerText="Date"?? ? 14.?????????????????? dataField="pubDate" width="150" /> ? 15.??????????? </mx:columns> ? 16.??????? </mx:DataGrid> ? 17.??????? <mx:LinkButton x="20" y="225" label="Read Full Post" ? 18.??????????????????? click="navigateToURL(new? ? 19. URLRequest(dgPosts.selectedItem.link));"/> ? 20.??????? <mx:TextArea x="20" y="175" width="400"/> ? 21.??? </mx:Panel> ? 22. </mx:Application> 这个例子的运行需要能够访问互联网,在本例中通过调用URL为http://weblogs . macromedia.com/mchotin/index.xml的HttpService,返回了一个XML文件,并将这个XML作为 DataGrid控件的dataProvider,从而通过DataGrid将XML文件中的数据展示出来。XML中的数据主要是网站最近的发帖记录。这个例子说明,HttpService的工作方式主要通过请求URL获取XML格式数据。 同HttpService类似,Flex 应用可以调用URL所表示WSDL 1.1服务,返回SOAP 1.1格式的调用结果。SOAP也是基于XML格式规范,因此,使用Httpservice和WebService组件同服务器之间的交互都是通过XML 进行的。下面是Adobe官方关于HttpService组件的例子应用。 ?? 1. <?xml version="1.0" encoding="utf-8"?> ?? 2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" ?? 3. layout="absolute" ?? 4. creationComplete="wsBlogAggr.getMostPopularPosts.send()"> ?? 5. <mx:WebService id="wsBlogAggr" ?? 6.????? wsdl="http://weblogs.macromedia.com/mxna/webservices/mxna2.cfc?wsdl"?? ?? 7.????? useProxy="false"> ?? 8.?????? <mx:operation name="getMostPopularPosts"> ?? 9.????????? <mx:request> ? 10.???????????? <daysBack>30</daysBack> ? 11.????????????? <limit>{cbxNumPosts.value}</limit> ? 12.????????? </mx:request> ? 13.????? </mx:operation> ? 14. </mx:WebService> ? 15. <mx:Panel x="10" y="10" width="475" height="400" layout="absolute" ? 16.???? title="Most Popular Posts"> ? 17.???? <mx:ComboBox x="30" y="25" id="cbxNumPosts" ? 18.??????? change="wsBlogAggr.getMostPopularPosts.send()"> ? 19.??????? <mx:Object label="Top 5" data="5" /> ? 20.??????? <mx:Object label="Top 10" data="10" /> ? 21.??????? <mx:Object label="Top 15" data="15" /> ? 22.???? </mx:ComboBox> ? 23.???? <mx:DataGrid x="30" y="75" id="dgTopPosts" width="400" ? 24.?????? dataProvider="{wsBlogAggr.getMostPopularPosts.lastResult}"> ? 25. <mx:columns> ? 26. <mx:DataGridColumn headerText="Top Posts"?? ? 27. dataField="postTitle"/> ? 28. <mx:DataGridColumn headerText="Clicks" dataField="clicks"?? ? 29. width="75"/> ? 30. </mx:columns> ? 31. </mx:DataGrid> ? 32. <mx:LinkButton x="30" y="250" ? 33. label="Select an item and click here for full post"/> ? 34. </mx:Panel> ? 35. </mx:Application> 在这个例子中,通过WebService组件调用了服务器所提供的WebService服务,返回SOAP格式的XML数据,根据请求参数,XML数据表示网站中最近30天的点击率排名前5、10或者15的博客。 通过这两个例子我们可以看到,使用HttpService和WebService无需第三方框架,在服务器端直接编写相应的服务即可,所以比较容易理解和使用。但是,无论使用HttpService还是WebService访问服务器,Flex客户端和服务器之间传递的都是XML数据,客户端和服务器端处理的也是XML数据。对于企业应用来说,客户端和服务器端交互的数据量往往很大,因此使用XML作为数据交换格式会降低传输效率和转换效率。同时,处理XML数据的代码也远比处理对象的代码繁琐,并且难以阅读和调试。因此,在企业应用开发中,客户端系统和服务器端系统之间采用HttpService 和WebService进行通信的部分较少,即使使用这两个组件,也应当用来传递少量、数据格式不易发生变化的数据。 在我们的企业应用开发中,Flex客户端与后台服务器之间的大量通信都是采用RemoteObject完成的。RemoteObject组件在“第三方软件”的配合下,能够调用后台服务器对象上的方法,比如Java对象或者.net对象上的方法,从而实现客户端与服务器端的通信。在客户端使用 RemoteObject可以直接将ActionScript对象作为调用的参数和返回结果。这一点听起来似乎有些神奇,但其实也很容易理解:Adobe 公司定义了一种二进制数据格式AMF(Action Message Format),用于客户端与服务器端的数据交互,AMF数据格式的规范已经公开,有兴趣的读者可以到以下网址下载AMF规范:http://download.macromedia.com/pub/labs/amf/amf3_spec_121207.pdf。 其实,使用AMF格式交换数据与使用XML进行数据交换的主要区别在于:AMF二进制数据的转换和传输效率更高,同时需要“第三方软件”用于解释 AMF格式数据。Flex客户端RemoteObject组件与服务器端通过HTTP协议传递AMF格式的二进制数据进行通信的大致过程如下: 1)客户端RemoteObject将调用参数中的ActionScript对象序列化为AMF数据格式,然后发出调用请求。 2)服务器的“第三方软件”获取HTTP请求流。 3)服务器的“第三方软件”对HTTP请求流进行解析,并且建立响应消息。对HTTP请求流进行解析,解析过程包括解释AMF格式数据,将 ActionScript对象的AMF数据按照事先确定的协议“反序列化”为服务器端对象,比如Java对象,然后用这些参数调用客户端指定的服务器对象上的方法。 4.1.1?? 确定Flex客户端系统和Java服务器端通信框架(2) 4)服务器的“第三方软件”将调用的结果“序列化”为AMF格式的数据流。 5)服务器发送HTTP响应给Flex客户端。 6)Flex客户端解释AMF格式数据流,将调用结果序列化为ActionScript对象。 7)下面我们给出一段Flex官方文档代码来展示RemoteObject对象的使用: ?? 1. <?xml version="1.0"?> ?? 2. <!-- fds/rpc/ROInAS.mxml -->?? ?? 3. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> ?? 4.???? <mx:Script> ?? 5.???????? <![CDATA[? ?? 6.???????????? import mx.controls.Alert;? ?? 7.???????????? import mx.rpc.remoting.RemoteObject;? ?? 8.???????????? import mx.rpc.events.ResultEvent;? ?? 9.???????????? import mx.rpc.events.FaultEvent;? ? 10.???????????? [Bindable]? ? 11.???????????? public var empList:Object;??????????? ? 12.???????????? public var employeeRO:RemoteObject;? ? 13.???????????? public function useRemoteObject(intArg:int,strArg:String):void {? ? 14.???????????????? employeeRO = new RemoteObject();? ? 15.???????????????? employeeRO.destination = "SalaryManager";? ? 16.???????????????? employeeRO.getList.addEventListener("result",?? ? 17. getListResultHandler);? ? 18.???????????????? employeeRO.addEventListener("fault",faultHandler);? ? 19.???????????????? employeeRO.getList(deptComboBox.selectedItem.data);? ? 20.???????????? }? ? 21.???????????? public function getListResultHandler(event:ResultEvent):void {? ? 22.????????????????? // 远程调用成功所要完成的处理。? ? 23.???????????????? empList=event.result;? ? 24.???????????? }? ? 25.? ? 26.???????????? public function faultHandler (event:FaultEvent):void {? ? 27.????????????? // 调用失败所要完成的处理。? ? 28.???????????????? Alert.show(event.fault.faultString,'Error');? ? 29.???????????? }? ? 30.???????? ]]> ? 31.???? </mx:Script> ? 32.???? <mx:ComboBox id="deptComboBox"/> ? 33. </mx:Application> 在上面的代码中,我们重点关注加黑的代码,首先看一下函数useRemoteObject,这个函数中首先使用语句: ?? 1. employeeRO = new RemoteObject(); 创建了一个RemoteObject对象employeeRO。然后通过语句: ?? 1. employeeRO.destination = "SalaryManager"; 将RemoteObject对象的destination属性赋值为一个字符串"SalaryManager",destination属性表示远程对象调用的“目的地”,请求发送到服务器端后,服务器端的“第三方软件”接收到请求后会检查配置文件,找到destination值所映射的“服务器端组件”,从而可以调用该组件上的方法。接下来使用语句: ?? 1. employeeRO.getList.addEventListener("result",getListResultHandler); 设置远程服务调用成功时的处理方法,使用语句: ?? 1. employeeRO.addEventListener("fault",faultHandler); 设置远程服务调用失败时的处理方法。最后,使用语句: ?? 1. employeeRO.getList(deptComboBox.selectedItem.data); 以deptComboBox.selectedItem.data为参数,调用destination 属性所映射的“服务器端组件”的getList方法。这里,“服务端组件”必须有一个名为getList的公开方法,调用“服务器端组件”的 getList方法是异步调用,因此它不会阻塞线程来等待调用结果的返回,调用结果的返回时会在getListResultHandler方法中进行处理。在getListResultHandler方法中,我们看到语句: ?? 1. empList=event.result; 该语句表示远程调用所返回的结果(event.result)可以直接赋值给ActionScrip对象。当然,后端返回的对象类型与Flex客户端的ActionScript对象类型要满足“第三方软件”所规定的对象类型之间的“映射”规则,这样,Flex就可以把后台返回的AMF数据流自动地序列化为ActionScript对象。 从上面的代码分析中我们可以看出:同传递XML方式相比,RemoteObject调用方式直接将ActionScript对象作为调用的参数和返回结果,这对于开发者编程特别方便。同时,读者也可能注意到,通过RemoteObject调用远程方法需要多写几行代码,但通过精巧的封装可以很好地解决这个问题。在第7章中,本书作者开发了一个RemoteObject封装框架,使运用RemoteObject对象进行远程方法调用更加优雅简洁,希望读者关注。 在上面的论述中多次提到了“第三方软件”,要使用RemoteObject组件进行远程方法调用,那么必须在服务器上部署和配置相应的“第三方软件”。“第三方软件”有两个最基本的作用: 服务器端对象序列化为AMF格式数据和将AMF格式数据反序列化为服务器端对象。 将客户端的请求映射为服务器端相应对象上的方法调用。 由于AMF规范已经公开,因此,有很多“第三方软件”支持不同的后台服务器端语言,在.net平台下比较著名的“第三方软件”为Midnight Coders WebORB(http://www.themidnightcoders.com/)。我们所关心的Java平台下的“第三方软件”有Adobe官方商业收费软件LifeCycle? Data? Services(LCDS)和Adobe官方开源软件BlazeDS。 BlazeDS是LCDS的开源版,只不过BlazeDS不具备LCDS的一些高级功能,比如: 高级客户端-服务器数据同步功能。 冲突检测/解决。 Adobe AIR应用的离线数据管理服务。 由RIA生成PDF等。 使用BlazeDS与LCDS进行企业应用开发的配置完全一样,因此,在不需要LCDS高级功能的情况下,完全可以使用BlazeDS替换LCDS 作为一种廉价方案,必须使用LCDS高级功能时,用户可以追加投资购买LCDS,因此基于BlazeDS企业应用可以很容易升级为基于LCDS的企业应用,这也是我们选择BlazeDS作为配合RemoteObject远程调用的“第三方软件”的主要原因。 因此,使用Flex+Java开发企业应用,我们主要使用RemoteObject+BlazeDS实现Flex端与Java端的通信。读者可以从以下网址查看BlazeDS的信息和下载BlazeDS框架:http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/。 总之,使用RemoteObject+BlazeDS作为Flex端同Java服务器端的通信框架有如下优点: 以二进制的AMF协议传递数据,转换和传输数据的性能高于XML格式,读者可以参考http://www.javaeye.com/news/3000一文中对几种RIA应用数据传输协议性能的比较。 使用RemoteObject+BlazeDS能够实现Flex对象与Java对象之间的自动转换,更加有利于开发者编程。 使用开源框架BlazeDS所开发的企业应用可以更容易地升级为采用高端商业软件LCDS作为数据通信框架的企业应用。 在第5章中,我们对BlazeDS框架进行了较为详细的介绍;在第7章中,我们在BlazeDS基础上进行了一些二次开发,使得BlazeDS框架更加适合多模块、大规模企业应用的部署和开发。当然,还有一些其他开源框架,比如Hessian和Granite也能够完成与BlazeDS类似的功能,开发者可以根据实际情况加以选择,但是由于它们的原理相同,所以可以使用相同架构方法和设计模式。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读