首页 RemObject SDK 快速入门

RemObject SDK 快速入门

举报
开通vip

RemObject SDK 快速入门Introdution RemObject SDK Introdution RemObject SDK    文/黄忠成  EMail:code6421@pchome.com.tw   前言     DELPHI 的3rd-Party 组件数量之多,远超过其它的开发工具,其用途之广可说创下前所未有的记录。这也为DELPHI 程序设计师省下许多重新制造轮子的时间,令系统开发速度倍增,同时减少了因实作码增加而使错误率升高。可惜的是VCL组件似乎都有着一个通病,就是缺少完整的说明档!许多VCL 组件甚至连范例都少的可怜,...

RemObject SDK 快速入门
Introdution RemObject SDK Introdution RemObject SDK    文/黄忠成  EMail:code6421@pchome.com.tw   前言     DELPHI 的3rd-Party 组件数量之多,远超过其它的开发工具,其用途之广可说创下前所未有的记录。这也为DELPHI 程序 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 师省下许多重新制造轮子的时间,令系统开发速度倍增,同时减少了因实作码增加而使错误率升高。可惜的是VCL组件似乎都有着一个通病,就是缺少完整的说明档!许多VCL 组件甚至连范例都少的可怜,幸运的是VCL 组件有个不成文的惯例,那就是多数都会附上完整的原始码,这一点可以稍减其说明档不足的现象。即便如此,说明档不足依旧对使用者造成相当大的困扰,时间就是金钱,在设计者探索原始码时,时间也一点点的流失了。本文所介绍的RemObjects SDK(以下简称RO) 也不能例外,由于这套组件的开发者只有两位,因此说明档一直都是相当短缺,有些地方甚至还有描述错误的情形,但这些缺点却无法掩盖其崭新的创意与高延展性的设计概念,这也是本文为何会出现在读者眼前的主要原因,RO是笔者看过VCL 组件中唯一令笔者感到惊艳的,当然! 这只是笔者个人的感觉,对读者不见得是如此,不过多了解一样东西,于汝何损?? 因此,细细品尝吧!!   PS:本文省略了讨论Web Services的基本知识部份,如果读者对于Web Services不熟悉,可参阅笔者的另几篇文章。   参考文章 电子商务新纪元 电子商务新纪元-失落的章节 Interface Designing    如何取得RO?      读者可至http://www.remobjects.com 取得测试版本,正式版本的定价是229 EUR,未来的Enterprise 版本的定价是603.90 EUR,这两个版本都附上了完整的原始码,目前RemObjects Enterprise SDK版本尚在Beta中,此版本拥有许多新功能,除了加强的RO 2.0之外还有抽象化数据存取的Data Abstract组件组,协助除错的Debug Server工具,以及完全使用C# 写成的RO.NET Client SDK。   PS:测试版本仅能运行于DELPHI IDE中,读者可利用Project Group来辅助运行Server端与Client端的程序。 PS2: RO 1.x支持DELPHI 5、6、7 Professional(DataSnap 部份需Enterprise),Kylix 3 for DELPHI。    What’s RemObjects SDK     随着各家厂商的强力背书与推销,Web Services 俨然成为未来分布式系统开发的主流架构,但是Web Services 至今仍然存在一些问 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 ,其中有些是属于规格的问题,有些则是先天上的限制,许多使用Web Services 开发系统的人都会有一个困扰,那就是效率不高,其原因很简单,XML 本身属于纯文字型态,加上必须依赖XML Parser 剖析XML 文件,在传输与解译上都是造成效率不彰的原因,这是Web Services 的先天限制,也是为了兼容性所付出的代价。当然! 如果网络频宽够大,计算机速度够快,这些都不是问题。但事实是目前的频宽与计算机速度还不足以胜任,这使得Web Services 的应用面缩减不少,因此许多的Web Servcies开发工具都会提供将SOAP讯息压缩的解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 ,藉此减少网络传输时间。另一个问题则是Web Services 必须依赖网络通讯协议,以现今的情况来看是以HTTP或TCP两种网络通讯协议为主流,假如客户想将系统安装于一台计算机上(不管是何理由,或许是因为节省金钱),Web Services 还是需要一个占用Port,就实务上来看这并不是什么大问题,但如果可以不占用Port岂不更好?? RO 就是这样一套组件,首先! RO 支持两种讯息 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 ,一个是SOAP(也就是Web Services)、另一个则是Binary(二进制讯息),支持SOAP 可让其它支持Web Services 的开发工具经由SOAP连上RO Server,支持Binary 可以让RO Client以更快的速度与RO Server 沟通,这比起将SOAP压缩后传递的效率高上许多,更令人兴奋的是RO允许设计者混用这两种讯息协议,也就是说只须撰写一个Server并放上这两个讯息组件,这一个Server 就可以同时服务使用SOAP 与 Binary 讯息的Client 端。有趣吗??更有趣的事情还在后面,RO 支持HTTP、TCP、Windows Message、DLL、UDP(2.0)、MSMQ(RO Enterprise) 多种通讯协议,并且允许设计者混用这些协议(DLL 是例外),简单的说! 就是写一个Server 同时允许Client 端以HTTP、TCP、Windows Message、UDP、MSMQ 方式连结,再加上之前所提的两种讯息标准,这个Server是不是更有趣了呢??呵!还没讲完呢,RO 不但具备这些特色,同时也允许设计者撰写自己的讯息协议与通讯协议,其步骤也不复杂,这些都是RO出色的主要原因。另外RO 也支持Kylix 3 for DELPHI,这代表着使用RO 可撰写Linux Server/Client,Windows Server/Client,日后的RO Client SDK.NET支援.NET Framework、Mono、Ractor,及Compact Framework,你能想象这种情况吗??   PS: TCP 与 Windows Message同时只能支持一种讯息格式,如SOAP 或是 Binary,原因是这两种协议并没有类似URL的概念,HTTP则无此限制,另外RO Enterprise SDK将会支持.NET Binary(.NET Remoting) 与RO Binary 两种格式。     初试RemObjects SDK     谈了这么多空话,现在是时候试试RO的能力了,这一节中以一个简单的计算器为范例(唔!!这是RO 送的,不要都不行….),在安装完RO 后组件盘上会出现RemObjects SDK 页,如下图所示: 其中分为五类,见下表: 组件 功能 类别 TROBinMessagw,TROSOAPMessage 讯息组件,用来处理讯息。 讯息类 TROIndyHTTPServer, TROIndyTCPServer, TROBPDXHTTPServer, TROBPDXTCPServer, TROWinMessageServer Server端组件,用来接收讯息,支持HTTP、TCP、Window Message与DLL(DLL 不需要组件,只需export 一个function即可) Server类 TROIndyHTTPChannel,TROIndyTCPChannel, TROBPDXHTTPChannel, TROBPDXTCPChannel, TROWinInetHTTPChannel, TRODLLChannel Client 端组件,用来送出讯息到Server端,支持HTTP,TCP,Windows Message与DLL。 Client类 TRODataSnapConnection,TRODataSnapProviderPublisher 支持DataSnap运作的组件,是的,RemObjects SDK允许使用DataSnap运行于其上。 DataSnap支援 TROWebBrokerServer Web Broker 支持,允许任何架构于Web Broker之上的网页程序直接挂载RemObjects SDK Server。 Web 支援 表中所提及的组件除BPDX(这是一组Internet 组件,名为DXSock,与Indy 有相同功能,但在效率与稳定性上都比Indy强,不过在易用性上却远不及Indy,而且她属于商业型组件,不过当读者购买RO后不须额外付费就可使用这套组件)、WebBrokerServer、DLLxxx之外,其它都会在本文中运用到。 在对这些组件有一个概略的认识后,现在就可以开始撰写一个简单的程序了,首先请开启New Dialogs 对话盒,切换到RemObjects SDK 这一页,其内有几个Wizard可协助设计者快速的产生骨架程序: 下表是这几个Wizard的简单说明: Wizard 说明 Apache 2 Shared Module Server Project 建立Apache 2 Shared Module的Server程序。 Apache Shared Module Server Project 建立 Apache 1.x Shared Module的Server程序。 DLL Server Project 建立DLL 的Server程序。 ISAPI/NSAPI Server Project 建立ISAPI、NSAPI 的Server程序。 RemObjects DataSnap Server Module 建立一个支持DataSnap操作的TRODataSnapDataModule。 Windows Executable Server Project 建立一个可独立执行的Server。 表中除了RemObjects DataSnap Server Module之外,其它都是用来建立一个新RO Server项目,这里请选择最简单的Windows Executable Server Project,按下OK后会开启下面这个窗口: 下表是这个窗口的字段说明: 字段 说明 Project Name 专案名称。 Service Library Name Library 名称,在RO 1.x 中这个参数的用途不大。 Service Name Web Service 的名称。 Server Class 通讯协议,见Server类组件。 Message Class 讯息协议,见Client 类组件。 Project Directory 项目存放的目录。 输入信息后按下OK就完成了骨架程序的建立工作了,这个程序已包含所有必须 用到的组件,接下来只需启动位于主选单上的RemObjects->Service Builder 工具定义Web Services 的 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 即可完成Server端的程序:  RO 预设会帮使用者产生两个方法,一个是Sum、另一个是GetServerTime(不要都不行…),为求简单! 这里直接运用这两个方法,不做任何的变动。请将Service Builder关闭后编译这个项目,此时RO 会跳出一个对话窗询问是否产生Service的定义与实作档案,请选择是,并且在产生后切换到CalcService_Impl.pas加入这两个方法的实作码: function TCalcService.Sum(const A: Integer; const B: Integer): Integer; begin   Result:=A+B; end;   function TCalcService.GetServerTime: DateTime; begin   Result:=Now; end; 最后将TROIndyHTTPServer(她被命名为ROServer)的Active设为Ture 就完成了Server端的程序了(假如选择的是BPDX类组件,那么这个动作必须写于程序中,因为BPDX不允许在设计时期启动)。 在撰写Client端程序之前必须先将Server程序执行起来,因为Client端必须由Server取得WSDL(事实上也可以直接由RODL(RO 的定义档)产生呼叫端的程序,后面会介绍这一部份),接着请开立一个新的项目,并且在其FORM 上放入TROWinInetHTTPChannel、TROSOAPMessage 两个组件,然后启动位于主选单上的RemObjects->Import Service 来读入WSDL定义(Import WSDL): 8099是TROIndyHTTPChannel 预设的Port,读者可经由TROIndyHTTPChannel.Port设定可更改其Port地址。 按下Import后会开出Service Builder,其中可以看到CalcService的定义,将Service Builder关闭后RO会要求输入文件名称,请将她命名为CalcService_Intf.pas。最后有个不方便的地方,由于Service Builder 的一个Bug,这个档案必须做一些修改才能正常运作: //CalcService_EndPointURI = 'http://localhost/soap'; CalcService_EndPointURI = 'http://localhost:8099/soap'; //CalcService_DefaultURN = 'urn-NewLibrary:CalcService'; CalcService_DefaultURN = 'CalcService'; 批注部份是原来的程序代码,粗体字部份是修改后的程序代码,这个Bug 已经被确认在下一个版本就会修正。 最后加上一些UI接口在FORM上,并加上呼叫Web Services 的程序代码就完成了Client端程序了,下图是UI 接口: 接着是呼叫Web Services的程序代码: …………… uses CalcService_Intf;   procedure TfmMain.btnCalcClick(Sender: TObject); var   vService:CalcService; begin   vService:= CoCalcService.Create(ROSOAPMessage1,ROWinInetHTTPChannel1);   try     lblResult.Caption:=IntToStr(vService.Sum(StrToInt(edtValue1.Text),StrToInt(edtValue2.Text)));   finally     vService:=Nil;   end; end;   procedure TfmMain.Button1Click(Sender: TObject); var   vService:CalcService; begin   vService:= CoCalcService.Create(ROSOAPMessage1,ROWinInetHTTPChannel1); try     lblServerTime.Caption:=DateTimeToStr(vService.GetServerTime);   finally     vService:=Nil;   end; end; 下图是这个程序的执行画面: 很简单是吧?? 唯一美中不足的是那个Bug…. 范例程序中附上了BizSnap、.NET、Java 三个Client端的原始码,有兴趣的读者可自行观看,这里就不再说明了。     异步呼叫模式     RO 支持异步呼叫模式,简单的说就是建立一个执行绪来呼叫远程的Web Services,这样在呼叫Web Services的期间主执行绪就可以做其它的事,不会因为长时间的呼叫而导致程序无响应的状况出现。由于目前版本的Service Builder并不会自动产生异步呼叫的Unit,因此使用者必须自行使用命令列的RODL2.EXE 来产生这个Unit,这个工具位于RemObjects SDK\Bin 目录下,只要键入下面这个命令就可产生出这个Unit: RODL2 /rodl:CalcLibrary.rodl /language:pascal /type:async CalcLibrary.rodl 是由Service Builder所产生出来的,通常位于Server所在目录下,/language:pascal则是指定产生pascal语言的程序代码(RO未来支持Pascal、C# 两种语言),/type:async则是表示产生出异步呼叫的Unit,完成后会产生一个名为CalcLibrary_Async.pas的程序文件,将它加入Client项目中,并修改呼叫Web Services部份的程序代码: uses CalcLibrary_Async;   procedure TfmMain.btnCalcClick(Sender: TObject); var   vService:CalcService_Async; begin   ROWinInetHTTPChannel1.TargetURL:='http://localhost:8099/soap';   vService:=CoCalcService_Async.Create(ROSOAPMessage1,ROWinInetHTTPChannel1);   try     vService.Invoke_Sum(StrToInt(edtValue1.Text),StrToInt(edtValue2.Text));     Sleep(3000);     lblResult.Caption:=IntToStr(vService.Retrieve_Sum);   finally     vService:=Nil;   end; end;   由于产生的CalcLibrary_Async.pas有一些小Bug,编译时uses 区段会有错误,请将uses CalcLibrary_Intf 改为CalcService_Intf,这样就可以正常编译并执行了。     多种讯息标准     前面的章节曾经提过,RO 支持混用多种通讯协议与讯息标准,这个功能使得Server的延展性大幅提升,要完成这个功能的步骤相当简单,请开启前一节的Server端专案,并在FORM上放上一个TROBINMessage组件,接着双按TROIndyHTTPServer.Dispatcher属性开出下面这个对话窗: 请按下Add的按纽,接着在Message处选择ROBinMessage1,这样就算完成了讯息标准的设定了,读者也可以藉由更改Path Info属性来变更这个讯息所对应的URL,除此之外,TROBinMessage支持将数据压缩后再传送,这个选项预设是开启的。现在Server已经可以支持SOAP、Binary两种讯息格式了,编译后执行程序后开启Client端的项目,并在FORM上放入一个TROBinMessage与切换使用讯息的RadioGroup组件: 最后修改呼叫端的程序代码: function TfmMain.GetService:CalcService; begin   Result:=Nil;   case RadioGroup1.ItemIndex of        0:         begin          ROWinInetHTTPChannel1.TargetURL:='http://localhost:8099/soap';          Result:=CoCalcService.Create(ROSOAPMessage1,ROWinInetHTTPChannel1);         end;        1:         begin          ROWinInetHTTPChannel1.TargetURL:='http://localhost:8099/bin';          Result:=CoCalcService.Create(ROBINMessage1,ROWinInetHTTPChannel1);         end;   end; end;   procedure TfmMain.btnCalcClick(Sender: TObject); var   vService:CalcService; begin   vService:=GetService;   try     lblResult.Caption:=IntToStr(vService.Sum(StrToInt(edtValue1.Text),StrToInt(edtValue2.Text)));   finally     vService:=Nil;   end; end;   procedure TfmMain.Button1Click(Sender: TObject); var   vService:CalcService; begin   vService:=GetService;   try     lblServerTime.Caption:=DateTimeToStr(vService.GetServerTime);   finally     vService:=Nil;   end; end; 粗体字是变动后的程序代码,主要在于切换不同的讯息标准。完成后执行程序,这时Client已经可以使用SOAP、Binary与Server端沟通了,当然! 两个不一样的Client可以同时使用两种不同的讯息标准与Server沟通。 要了解SOAP 与Binary 的差别,只需使用TCPTrace 这个工具来观察Client与Server的讯息流动状态:   SOAP BINARY 两种讯息有着近10 倍的差距。     讯息编码     除了支持SOAP与BINARY讯息格式之外,RO 也允许将讯息编码,这对需要较高安全性的Multi-Tier系统来说相当有用,要为系统加入这个功能,只须要设定ROServer的Encryption中的几个属性即可,首先选取欲使用的编码算法:   接着再设定EncryptionRecvKey、EncryptionSendKey就可以了,这两个特性还支持多种算法,这可以防堵有能力的破解高手经由反组译取得加密与解密的Key: 如有需要,也可以将Encryption.UseCompression设为True,这样更增加讯息在传送期间的安全性。     多种通讯协议    上一节中实作了支持多种讯息的Server、Client端,这一节将继续实作支持多种通讯协议的Server端与使用不同通讯协议的Client端。首先开启Server端的项目,在FORM上放入TROIndyTCPServer、TROWinMessageServer,接着设定TROWinMessageServer.ServerID 为”ROCalcServer”,完成后请双按TROIndyTCPServer.Dispatcher与TROWinMessageServer.Dispatcher来设定其支持的讯息组件,由于这两种Server只允许一个讯息组件存在,在本例中选择Binary,最后将这两个组件的Active设成Ture就完成了,下面两个程序是使用TCP与Windows Message的Client端程序代码,完整的程序可于范例目录中找到:   TCPChannel procedure TfmMain.btnCalcClick(Sender: TObject); var   vService:CalcService; begin   vService:=CoCalcService.Create(ROBINMessage1,ROIndyTCPChannel1);   try     lblResult.Caption:=IntToStr(vService.Sum(StrToInt(edtValue1.Text),StrToInt(edtValue2.Text)));   finally     vService:=Nil;   end; end;   procedure TfmMain.Button1Click(Sender: TObject); var   vService:CalcService; begin   vService:=CoCalcService.Create(ROBINMessage1,ROIndyTCPChannel1);   try     lblServerTime.Caption:=DateTimeToStr(vService.GetServerTime);   finally     vService:=Nil;   end; end;   Window Message Channel procedure TfmMain.btnCalcClick(Sender: TObject); var   vService:CalcService; begin   vService:=CoCalcService.Create(ROBINMessage1,ROWinMessageChannel1);   try     lblResult.Caption:=IntToStr(vService.Sum(StrToInt(edtValue1.Text),StrToInt(edtValue2.Text)));   finally     vService:=Nil;   end; end;   procedure TfmMain.Button1Click(Sender: TObject); var   vService:CalcService; begin   vService:=CoCalcService.Create(ROBINMessage1,ROWinMessageChannel1);   try     lblServerTime.Caption:=DateTimeToStr(vService.GetServerTime);   finally     vService:=Nil;   end; end; 执行画面与之前的程序大同小异,这里就不再贴上来了。     复杂数据型态(Complex Type)     Web Services 除了可以表示简单的数据型态之外,也可以表示复杂的数据型态,这一部份在RO中称之为Struct(结构),这一节中将介绍如何在RO中定义这种数据型态。 其实步骤相当简单,只需在Service Builder中按下Struct按纽新增一个Struct 数据型态,并在其下方定义内部的结构就可以了,如下图: 然后定义一个方法,将其传回值设成这个Struct 即可;   下面是这个方法的实作码:   function TComplexTypeService.GetPerson: Person; begin   Result:=Person.Create;   Result.Name:='黄忠成';   Result.Age:=18; end;   Client 端部份只需以Import WSDL 或是Import RODL(选择位于Server项目目录下的那个ComplexTypeService.rodl)即可产生Invoke 部份的程序代码,最后只要加入呼叫Web Services的程序代码就算完成Client端了: Procedure TfmMain.Button1Click(Sender: TObject); var   vService:ComplexTypeService;   vData:Person; begin   vService:=CoComplexTypeService.Create(ROSOAPMessage1,ROWinInetHTTPChannel1);   try     vData:=vService.GetPerson;     try      edtName.Text:=vData.Name;      edtAge.Text:=IntToStr(vData.Age);     finally      vData.Free;     end;   finally     vService:=Nil;   end; end;   完整的程序请参照范例,除了Struct之外,眼尖的读者应该也看到了RO 支持Enum(列举)、Array(数组)型态,这些型态的使用方式大同小异,日后2.x 会增加Set与Exception的型态定义。 另外有一点必须注意,当Client端是.NET时RO会产生中文乱码的问题,这一点目前笔者与RO Team正在讨论中,下一版本就可解决。     DataSnap 支援     前面曾经提过,RO 允许DataSnap运行于其上,这给了程序设计师一个相当大的礼物,以往DataSnap只能运行于CORBA、DCOM、Socket、SOAP 之上,前面三个通讯协议都属于封闭型的,而SOAP又会遭遇效率低落的问题,使用RO的话不但可以使用HTTP、TCP、Windows Message、DLL,又可以混用SOAP与Binary两种讯息格式,同时具备了延展性与效率,其建构步骤也相当简单,这一节中将撰写一个简单的RO DataSnap Server与Client端。首先请建立一个新项目,并如往常般放置TROIndyHTTPServer、TROSOAPMessage、TROBinMessage至FORM上,接着开启New Dialogs 来加入一个RO DataSnap DataModule: 在其上放置TDatabase、TSession、TQuery、TDataSetProvider等组件: 接着照以往设定Remote DataModule 般设定这几个组件的关联,最后双按DataModule.Providers 加入欲开放给Client端的DataSetProvider 就完成了Server端程序了。 Client端程序也很简单,只需放置需要的UI组件及TROWinInetHTTPChannel、TROBinMessage、TRODataSnapConnection 再做一些设定即可,这部份有一点需注意,由于Indy 的Bug,因此无法在Design Time 混用TRODataSnapConnection与TROIndyHTTPChannel,因此请先利用TROWinInetHTTPChannel,待设定好各ClientDataSet的ProviderName后再将TROWinInetHTTPChannel换成TROIndyHTTPChannel(如果需要的话)。 现在设定TROWinInetHTTPChannel.TargetURL 为http://localhost:8099/bin,并将其Connected设成True,接着切换至TRODataSnapConnection设定Message、Channel这两个特性值分别为TROWinInetHTTPChannel 及 TROBinMesage后将Connect 设成True,现在放置一个TClientDataSet至Form上,并设定其RemoteServer为TRODataSnapConnection,完成后应该就能在ProvideName的下拉盒中找到DataSetProvider1了,最后放置一个DataSource与相关的UI组件就完成了: 一个简单但完整的3-Tier 程序就完成了。     PacketRecords     DataSnap的PacketRecords 一直都是多数人的最爱,RO 也支持这个功能,但事实上这只是RO 众多对象建立模式的一种,下面的章节中会介绍RO 的对象模式与设计概念,这里只需修改DataSnap Server 的Data Module 程序代码就可支持这个功能: Initialization   { To adjust scalability of the DataSnapModule and avoid recreation of     instances for each roundtrip, you might want to choose a  different     ClassFactory type.       Make sure to check the following url for more information:     http://www.remobjects.com/page.asp?id=C771266D-6D99-4301-B77D-D7B92D3BCD4D }     //TROPooledClassFactory.Create('IAppServer', Create_DataSnapModule, TIAppServer_Invoker, 25);   //TROClassFactory.Create('IAppServer', Create_DataSnapModule, TIAppServer_Invoker);   TROPerClientClassFactory.Create('IAppServer', Create_DataSnapModule, TIAppServer_Invoker, 20*60 { seconds Session timeout }); TROPerClientClassFactory 会为每一个Client建立一个专有的Service 对象,因此运用她就可使PacketRecords 功能正常运作。     DataSnap Server 与 Method     以往在撰写DataSnap Server时常常会定义一些供Client端呼叫的方法,在RO中一样可以这样做,不过因为RO目前版本的一些限制,所以无法很便利的定义这些方法,这点日后会改善(事实上,在RO 2.x Beta中这一点已经解决了)。     RemObjects SDK 的Server 与Client运作模式    相信许多读者一定很好奇,RO 内部到底是如何处理Client端的呼叫,Server又是如何将SOAP转换为呼叫动作执行目的对象中的方法呢?? 事实上,在这一点上RO有非常独到的见解,在详细介绍其运作模式之前,笔者先就目前几种主流的Web Services 开发工具的运作模式做一简单的介绍,其中包括BizSnap、.NET Web Services、.NET Remoting与Java。   BizSnap与.NET Remoting 的Server端运作模式     BizSnap与.NET Remoting有着非常相似的处理模式,甚至可以说除了实作的语言与编译技术不同之外,其主要的概念是完全相同的,下图是其运作模式的流程图: 当Client 将Request 送达Server端后,会经过一个Message Dispatcher机制,这个机制大多是几个重要的组件合作完成,主要在于解出Request中对于所要求对象的描述,以及欲呼叫的方法等信息,有了这些信息后Dispatcher就可以找到对应的对象与方法,接着就开始了呼叫动作,由于Request 是SOAP讯息格式,并不能直接用来呼叫对象的方法,因此得先将SOAP讯息转化为Stack(堆栈),完成这个转换动作后就到了这种处理模式中的核心概念了,也就是建立起目的对象并呼叫对应的方法,这个动作非常依赖前面的Message To Stack程序,因为这个程序会将SOAP讯息转化为Stack,有了Stack之后Push Stack and Call Method 动作才能正确的执行,那么如何呼叫目的方法呢?很简单,只要利用该语言所提供的RTTI信息(.NET 中则是MetaData),就可取得该方法的内存地址,接着只须以低阶的ASM 或IL 所提供的CALL 指令即可呼叫该方法,由于已将SOAP讯息转为Stack,因此传入参数就不是问题了。在呼叫结束后,Stack 中已经有了传回的参数,接着只须将Stack转回SOAP 讯息传回给Client端就可以了。   BizSnap、.NET Remoting 的Client端运作模式    上一节所提的是Server端接到要求后的处理流程,这一节将介绍Client端的呼叫动作, 下图是大略的流程: 不管是BizSnap或是.NET Remoting,当Client端欲呼叫Web Services时都会经过一个Proxy Object,于BizSnap中这个对象就是THTTPRIO,.NET Remoting中这个对象就是RealProxy,由于这个对象属于静态的,因此在使用之前必需将其转型回目的对象的型别,当Client端下达转型动作后整个魔法就开始运行了,首先Proxy Object会利用RTTI或是MetaData信息取得欲转型的类别信息,并依照这些信息建立起一个兼容于该类别的对象(Transparent Proxy Object),接着将这个对象中的所有方法地址替换为Stub Method,Stub Method 做的事情很单纯,只是将Stack转为SOAP Message后送出,当Server端回应后再将SOAP Message转换为Stack 后返回,这样整个Client端呼叫动作就完成了,下次再呼叫时只需由Cache中取出这个已建立好的Transparent Proxy Object,就可以直接进行呼叫,这可以避免因反复以RTTI或是MetaData建立Transparent Proxy Object而失去效率。 BizSnap、.NET Remoting 的处理模式属于较低阶的方法,这种方法的坏处大于好处, 好处是设计者可以完全不了解其内部运作,以传统方式来撰写程序,坏处是过度依赖编译器及平台,增加日后移植到其它语言或平台上的难度,另外使用动态产生对象类别的低阶技术很容易引发效率及内存管理的问题。     .NET Web Services 与Java     .NET Web Services 与Java 的处理模式与.NET Remoting、BizSnap大同小异,其间最大的不同之处在于这种模式利用了其语言的特性,采动态呼叫的方式来执行呼叫的动作,而非如先前所提的模式在Stack与Message之间进行转换,这种模式简单的在Client端与Server端之间插入一个预先编译好的Proxy Object,这个Object是由WSDL所产生的,其中定义了所有目标对象的方法,在这些方法中简单的将传入的参数转换为SOAP Message,将传回的讯息转回参数,其间的运作完全属于高阶型态:   Client 端的呼叫   Server端的处理 由上面两个图上可看出,这种模式讲求简单,Client端的Stub Method 由原本的一个变成每个方法一个,Server端则由原本的低阶CALL命令转为语言本身所提供的动态呼叫功能。这样的简化带来了效率,由于Client端不再经过动态转型与建立中介对象的动作,因此在效率上有显著的提升,也因为少了这些低阶的动作,内存管理上显得容易多了。但这种方式却有着另外的几个缺点,由于Proxy Object的程序代码增加,相对的程序所占用的内存也随之变大,另外Server采用动态呼叫的方式来唤起方法,这种方式通常效率不高。     RemObjects SDK     前面所提的两种模式皆有其优缺点,RO 在这方面则提出了另一个崭新的处理模式, 下图是RO 的Server端处理模式:   上图中大约与前面所提及的模式相同,其中不同之处在于Invoke Object,这是一个预先编译好的对象,其作用与.NET Web Services的Proxy Object相同,这个对象中所有方法都是Stub Method,将SOAP讯息转为参数后呼叫Real Object(Implement Object)的方法,完成后将参数转回讯息后返回Client端。那么这种模式有何独到之处呢??答案是效率,整个动作之中看不到低阶的Stack或是动态呼叫,没有这些动作的加入,当然速度上也就加快不少。   RO 的Client端处理方式与Server端大同小异,因此结论是! RO 没有用到任何的中介技术,也没有用到任何语言独有的功能,这也是RO .NET 为何能在短短的几个月内就能完成的主要原因。下面是CalcService 的xxx_Intf.pas、xxx_Invk.pas、xxx_Impl.pas的原始码,交替着看应可让读者更清楚这种模式的运作。   unit CalcLibrary_Invk;   {----------------------------------------------------------------------------} { This unit was automatically generated by the RemObjects SDK after reading  } { the RODL file associated with this project .                               } {                                                                            } { Do not modify this unit manually, or your changes will be lost when this   } { unit will regenerated the next time you compile the project.               } {----------------------------------------------------------------------------}   interface   uses   {vcl:} Classes,   {RemObjects:} uROServer, uROServerIntf, uROTypes, uROClientIntf,   {Generated:} CalcLibrary_Intf;   type   TCalcService_Invoker = class(TROInvoker)   private   protected   published     procedure Invoke_Sum(const __Instance:IInterface; const __Message:IROMessage; const __Transport:IROTransport);     procedure Invoke_GetServerTime(const __Instance:IInterface; const __Message:IROMessage; const __Transport:IROTransport);   end;   implementation   uses   {RemObjects:} uRORes;   { TCalcService_Invoker }   procedure TCalcService_Invoker.Invoke_Sum(const __Instance:IInterface; const __Message:IROMessage; const __Transport:IROTransport); { function Sum(const A: Integer; const B: Integer): Integer; } var   A: Integer;   B: Integer;   Result: Integer; begin   try     __Message.Read('A', TypeInfo(Integer), A, []);     __Message.Read('B', TypeInfo(Integer), B, []);       Result := (__Instance as CalcService).Sum(A, B);       __Message.Initialize(__Transport, 'CalcLibrary', 'CalcService', 'SumResponse');     __Message.Write('Result', TypeInfo(Integer), Result, []);     __Message.Finalize;     finally   end; end;   procedure TCalcService_Invoker.Invoke_GetServerTime(const __Instance:IInterface; const __Message:IROMessage; const __Transport:IROTransport); { function GetServerTime: DateTime; } var   Result: DateTime; begin   try       Result := (__Instance as CalcService).GetServerTime;       __Message.Initialize(__Transport, 'CalcLibrary', 'CalcService', 'GetServerTimeResponse');     __Message.Write('Result', TypeInfo(DateTime), Result, [paIsDateTime]);     __Message.Finalize;     finally   end; end;   end.   unit CalcLibrary_Intf;   {----------------------------------------------------------------------------} { This unit was automatically generated by the RemObjects SDK after reading  } { the RODL file associated with this project .                               } {                                                                            } { Do not modify this unit manually, or your changes will be lost when this   } { unit will regenerated the next time you compile the project.               } {----------------------------------------------------------------------------}   interface   uses   {vcl:} Classes, TypInfo,   {RemObjects:} uROProxy, uROTypes, uROClientIntf;   const   LibraryUID = '{D62FF60B-5567-43E3-8386-161869372E27}';     type   { Forward declarations }   CalcService = interface;     { CalcService }     { Description:      
本文档为【RemObject SDK 快速入门】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_554532
暂无简介~
格式:doc
大小:921KB
软件:Word
页数:31
分类:互联网
上传时间:2011-05-03
浏览量:21