1、Introdution RemObject SDK文/黄忠成 EMail:.tw前言DELPHI 的 3rd-Party 组件数量之多,远超过其它的开发工具,其用途之广可说创下前所未有的记录。这也为 DELPHI 程序设计师省下许多重新制造轮子的时间,令系统开发速度倍增,同时减少了因实作码增加而使错误率升高。可惜的是 VCL 组件似乎都有着一个通病,就是缺少完整的说明档!许多 VCL 组件甚至连范例都少的可怜,幸运的是 VCL 组件有个不成文的惯例,那就是多数都会附上完整的原始码,这一点可以稍减其说明档不足的现象。即便如此,说明档不足依旧对使用者造成相当大的困扰,时间就是金钱,在设计者探索原始
2、码时,时间也一点点的流失了。本文所介绍的 RemObjects SDK(以下简称 RO) 也不能例外,由于这套组件的开发者只有两位,因此说明档一直都是相当短缺,有些地方甚至还有描述错误的情形,但这些缺点却无法掩盖其崭新的创意与高延展性的设计概念,这也是本文为何会出现在读者眼前的主要原因,RO 是笔者看过 VCL 组件中唯一令笔者感到惊艳的,当然! 这只是笔者个人的感觉,对读者不见得是如此,不过多了解一样东西,于汝何损? 因此,细细品尝吧!PS:本文省略了讨论 Web Services 的基本知识部份,如果读者对于 Web Services 不熟悉,可参阅笔者的另几篇文章。参考文章电子商务新纪元
3、 电子商务新纪元-失落的章节 Interface Designing如何取得 RO?读者可至 http:/ 取得测试版本,正式版本的定价是 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 中
4、,读者可利用 Project Group 来辅助运行 Server 端与 Client 端的程序。PS2: RO 1.x 支持 DELPHI 5、6、7 Professional(DataSnap 部份需 Enterprise),Kylix 3 for DELPHI。Whats RemObjects SDK随着各家厂商的强力背书与推销,Web Services 俨然成为未来分布式系统开发的主流架构,但是 Web Services 至今仍然存在一些问题,其中有些是属于规格的问题,有些则是先天上的限制,许多使用 Web Services 开发系统的人都会有一个困扰,那就是效率不高,其原因很简单,X
5、ML 本身属于纯文字型态,加上必须依赖 XML Parser 剖析 XML 文件,在传输与解译上都是造成效率不彰的原因,这是 Web Services 的先天限制,也是为了兼容性所付出的代价。当然! 如果网络频宽够大,计算机速度够快,这些都不是问题。但事实是目前的频宽与计算机速度还不足以胜任,这使得 Web Services 的应用面缩减不少,因此许多的 Web Servcies 开发工具都会提供将 SOAP 讯息压缩的解决方案,藉此减少网络传输时间。另一个问题则是 Web Services 必须依赖网络通讯协议,以现今的情况来看是以 HTTP或 TCP 两种网络通讯协议为主流,假如客户想将系
6、统安装于一台计算机上(不管是何理由,或许是因为节省金钱),Web Services 还是需要一个占用 Port,就实务上来看这并不是什么大问题,但如果可以不占用 Port 岂不更好? RO 就是这样一套组件,首先! RO 支持两种讯息标准,一个是 SOAP(也就是 Web Services)、另一个则是 Binary(二进制讯息) ,支持SOAP 可让其它支持 Web Services 的开发工具经由 SOAP 连上 RO Server,支持 Binary 可以让 RO Client 以更快的速度与 RO Server 沟通,这比起将 SOAP 压缩后传递的效率高上许多,更令人兴奋的是 RO
7、允许设计者混用这两种讯息协议,也就是说只须撰写一个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 是
8、不是更有趣了呢 ?呵!还没讲完呢,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,原
9、因是这两种协议并没有类似 URL 的概念,HTTP 则无此限制,另外 RO Enterprise SDK 将会支持.NET Binary(.NET Remoting) 与 RO Binary 两种格式。初试 RemObjects SDK谈了这么多空话,现在是时候试试 RO 的能力了,这一节中以一个简单的计算器为范例(唔!这是 RO 送的,不要都不行.),在安装完 RO 后组件盘上会出现 RemObjects SDK 页,如下图所示:其中分为五类,见下表:组件 功能 类别TROBinMessagw,TROSOAPMessage讯息组件,用来处理讯息。 讯息类TROIndyHTTPServer,T
10、ROIndyTCPServer,TROBPDXHTTPServer,TROBPDXTCPServer,TROWinMessageServerServer 端组件,用来接收讯息,支持 HTTP、TCP、Window Message 与 DLL(DLL 不需要组件,只需 export 一个function 即可)Server 类TROIndyHTTPChannel,TROIndyTCPChannel,TROBPDXHTTPChannel,TROBPDXTCPChannel,TROWinInetHTTPChannel,TRODLLChannelClient 端组件,用来送出讯息到 Server 端,
11、支持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 有
12、相同功能,但在效率与稳定性上都比 Indy 强,不过在易用性上却远不及 Indy,而且她属于商业型组件,不过当读者购买 RO 后不须额外付费就可使用这套组件)、WebBrokerServer、DLLxxx 之外,其它都会在本文中运用到。在对这些组件有一个概略的认识后,现在就可以开始撰写一个简单的程序了,首先请开启New Dialogs 对话盒,切换到 RemObjects SDK 这一页,其内有几个 Wizard 可协助设计者快速的产生骨架程序:下表是这几个 Wizard 的简单说明 :Wizard 说明Apache 2 Shared Module Server Project 建立 Apac
13、he 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
14、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 类组
15、件。Message Class 讯息协议,见 Client 类组件。Project Directory 项目存放的目录。输入信息后按下 OK 就完成了骨架程序的建立工作了,这个程序已包含所有必须用到的组件,接下来只需启动位于主选单上的 RemObjects-Service Builder 工具定义 Web Services 的方法即可完成 Server 端的程序:RO 预设会帮使用者产生两个方法,一个是 Sum、另一个是 GetServerTime(不要都不行) ,为求简单! 这里直接运用这两个方法,不做任何的变动。请将 Service Builder 关闭后编译这个项目,此时 RO 会跳出一
16、个对话窗询问是否产生 Service 的定义与实作档案,请选择是,并且在产生后切换到 CalcService_Impl.pas 加入这两个方法的实作码 :function TCalcService.Sum(const A: Integer; const B: Integer): Integer;beginResult:=A+B;end;function TCalcService.GetServerTime: DateTime;beginResult:=Now;end;最后将 TROIndyHTTPServer(她被命名为 ROServer)的 Active 设为 Ture 就完成了 Serve
17、r 端的程序了(假如选择的是 BPDX 类组件,那么这个动作必须写于程序中,因为 BPDX 不允许在设计时期启动)。在撰写 Client 端程序之前必须先将 Server 程序执行起来,因为 Client 端必须由 Server 取得WSDL(事实上也可以直接由 RODL(RO 的定义档) 产生呼叫端的程序,后面会介绍这一部份),接着请开立一个新的项目,并且在其 FORM 上放入TROWinInetHTTPChannel、TROSOAPMessage 两个组件,然后启动位于主选单上的RemObjects-Import Service 来读入 WSDL 定义(Import WSDL):8099
18、是 TROIndyHTTPChannel 预设的 Port,读者可经由 TROIndyHTTPChannel.Port 设定可更改其 Port 地址。按下 Import 后会开出 Service Builder,其中可以看到 CalcService 的定义,将 Service Builder关闭后 RO 会要求输入文件名称,请将她命名为 CalcService_Intf.pas。最后有个不方便的地方,由于 Service Builder 的一个 Bug,这个档案必须做一些修改才能正常运作:/CalcService_EndPointURI = http:/localhost/soap;CalcS
19、ervice_EndPointURI = http:/localhost:8099/soap;/CalcService_DefaultURN = urn-NewLibrary:CalcService;CalcService_DefaultURN = CalcService;批注部份是原来的程序代码,粗体字部份是修改后的程序代码,这个 Bug 已经被确认在下一个版本就会修正。最后加上一些 UI 接口在 FORM 上,并加上呼叫 Web Services 的程序代码就完成了 Client端程序了,下图是 UI 接口:接着是呼叫 Web Services 的程序代码:uses CalcService
20、_Intf;procedure TfmMain.btnCalcClick(Sender: TObject);varvService:CalcService;beginvService:= CoCalcService.Create(ROSOAPMessage1,ROWinInetHTTPChannel1);trylblResult.Caption:=IntToStr(vService.Sum(StrToInt(edtValue1.Text),StrToInt(edtValue2.Text);finallyvService:=Nil;end;end;procedure TfmMain.Button
21、1Click(Sender: TObject);varvService:CalcService;beginvService:= CoCalcService.Create(ROSOAPMessage1,ROWinInetHTTPChannel1);trylblServerTime.Caption:=DateTimeToStr(vService.GetServerTime);finallyvService:=Nil;end;end;下图是这个程序的执行画面:很简单是吧? 唯一美中不足的是那个 Bug.范例程序中附上了 BizSnap、.NET、Java 三个 Client 端的原始码,有兴趣的读者
22、可自行观看,这里就不再说明了。异步呼叫模式RO 支持异步呼叫模式,简单的说就是建立一个执行绪来呼叫远程的 Web Services,这样在呼叫 Web Services 的期间主执行绪就可以做其它的事,不会因为长时间的呼叫而导致程序无响应的状况出现。由于目前版本的 Service Builder 并不会自动产生异步呼叫的 Unit,因此使用者必须自行使用命令列的 RODL2.EXE 来产生这个 Unit,这个工具位于RemObjects SDKBin 目录下,只要键入下面这个命令就可产生出这个 Unit:RODL2 /rodl:CalcLibrary.rodl /language:pascal
23、 /type:asyncCalcLibrary.rodl 是由 Service Builder 所产生出来的,通常位于 Server 所在目录下,/language:pascal 则是指定产生 pascal 语言的程序代码(RO 未来支持 Pascal、C# 两种语言) ,/type:async 则是表示产生出异步呼叫的 Unit,完成后会产生一个名为 CalcLibrary_Async.pas的程序文件,将它加入 Client 项目中,并修改呼叫 Web Services 部份的程序代码:uses CalcLibrary_Async;procedure TfmMain.btnCalcClic
24、k(Sender: TObject);varvService:CalcService_Async;beginROWinInetHTTPChannel1.TargetURL:=http:/localhost:8099/soap;vService:=CoCalcService_Async.Create(ROSOAPMessage1,ROWinInetHTTPChannel1);tryvService.Invoke_Sum(StrToInt(edtValue1.Text),StrToInt(edtValue2.Text);Sleep(3000);lblResult.Caption:=IntToStr
25、(vService.Retrieve_Sum);finallyvService:=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 组件:最后修改呼叫端的程序代码: