三:创建多层应用程序

第三章 创建多层应用程序
  一个多层的Client/Server应用程序在逻辑上划分为几个部分,分别在不同的机器上运行,这些机器既可以在一个局域网内,也可以在Internet上。多层体系结构最大的优势可以概括为两点,一是集中化的商业逻辑,另一个是客户程序可以做得很“瘦”。
  目前较常见的是三层的体系结构,其中,最关键的是应用服务器,它在三层体系结构中起了承上启下的作用,所以,应用服务器又叫Data Broker。Delphi4可以创建应用服务器,也可以创建“瘦”客户。如果不怕麻烦的话,也可以创建数据库后端。
  在更复杂的多层体系结构中,“瘦”客户与远程服务器之间可以加入更多的服务中间件,例如,可以加入一个安全服务中间件,或者加入一个转换中间件,专门用来处理不同平台共享数据的问题。一旦您真正理解了三层的体系结构,多层的体系结构就迎刃而解。
3.1 多层体系结构的概述
  Delphi 4对多层体系结构的支持主要得益于它的MIDAS技术。MIDAS是Multi-tier Distributed Application Services Suite的简称。MIDAS技术与Delphi 4中的另一个关键技术DAX配合起来使用,可以使多层的体系结构分布在Intrenet/Intranet上。
3.1.1 多层体系结构的优势
  在多层体系结构中,由于服务器集中实现了应用逻辑(又称商业规则),客户程序可以把重点放在显示数据和与用户交互上,客户程序甚至都不需要知道数据存储在哪儿。
  具体来说,多层的体系结构具有如下优势:
  在一个共享的中间层封装了商业规则。不同的客户程序可以共享同一个中间层,而不必由每个客户程序单独实现商业规则。
  客户程序可以做得很“瘦”。因为很多复杂的工作由应用服务器代劳了,客户程序只需要关注用户界面本身。“瘦”客户程序更容易发布、安装、配置和维护。
  实现了分布式数据处理。把一个应用程序分布在几个机器上运行,可以提高应用程序的性能,通过冗余配置还可以保证不会因为局部故障导致整个应用程序崩溃。
  有利于安全。可以把一些敏感的功能放在有严密防护措施的层上,同时又不至于使用户界面变得复杂。Delphi 4中的CORBA或MTS支持较复杂的安全机制。
3.1.2 MIDAS技术
  MIDAS技术是多层体系结构的关键。无论是应用服务器端还是客户端,MIDAS技术需要有DBCLIENT.DLL的支持,这个动态链接库用于管理数据包。发布MIDAS应用程序时需要购买服务器许可。
  基于MIDAS的多层应用程序需要用到一些特殊的构件,这些构件分为四大种类:

     1. 对象库中的远程数据模块。远程数据模块与普通的数据模块有些相似,不同的是,远程数据模块可以作为COM服务器或CORBA服务器让客户程序访问它的接口。
  2. TDataSetProvider和TProvider构件。这两个构件用在应用服务器端,主要作用是提供IProvider接口,客户程序通过IProvider接口获得数据和更新数据集。
  3. TClientDataSet构件。这是一个从TDataset继承下来的但不需要BDE的构件。

     4. MIDAS连接构件。包括TDCOMConnection、TSocketConnection、TCorbaConnection TOLEnterpriseConnection、TMIDASConnection和TRemoteServer。其中,TMIDASConnection和TRemoteServer是为了兼容Delphi3的代码而保留的。MIDAS连接构件的作用是为客户程序定位服务器和IProvider接口。每个MIDAS连接构件都以一种特定的通讯协议工作。
3.1.3 MIDAS应用程序是怎样工作的
  用户首先要启动客户程序,客户程序将试图连接应用服务器,如果应用服务器还没有运行,客户程序将激活应用服务器,并从中获得IProvider接口。
  客户程序向应用服务器请求数据。如果TClientDataSet的FetchOnDemand属性设为True,客户程序会根据需要自动检索附加的数据包如BLOB字段的值或嵌套表的内容。否则,客户程序需要显式地调用GetNextPacket才能获得这些附加的数据包。
  应用服务器收到客户程序的请求后,就从远程数据库服务器那儿检索数据,并打包返回给客户程序
  客户程序收到数据包后把包打开,然后显示或进行处理。
  用户对数据进行编辑修改,然后向应用服务器申请更新数据,实际上也要打包。
  应用服务器收到客户程序的申请后,就向远程数据库服务器申请更新数据。如果出错,应用服务器就把出错的记录返回给客户程序去核对。
  客户程序核对并修改了数据后,既可以放弃此次更新,也可以继续此次更新。
3.1.4 客户程序的结构
  对于最终用户来说,多层体系结构中的客户程序与两层体系结构中的应用程序没有什么区别,在结构上,客户程序就好像一个基于文件的单层应用程序一样,仍然通过标准的数据控件与用户交互。但与单层应用程序不同的是,多层体系结构中的客户程序是通过应用服务器提供的IProvider接口获得数据的,也通过IProvider接口申请更新数据。
  注意:当使用MTS的时候,可以选择不使用IProvider接口。不使用IProvider接口的好处是,可以充分发挥MTS在处理事务方面的特长。
  在客户程序中,MIDAS连接构件扮演着极其重要的角色。不同的MIDAS连接构件使用不同的通讯协议:
. TDCOMConnection DCOM
. TSocketConnection Windows Sockets (TCP/IP)l
. TOLEnterpriseConnection OLEnterprise (RPCs)
. TCorbaConnection CORBA (IIOP)
  TRemoteServer和TMIDASConnection是为了兼容Delphi 3的代码而保留的。
3.1.5 应用服务器的结构
  应用服务器的关键部件是远程数据模块,它提供了IDataBroker接口。当客户程序与应用服务器建立了连接,就通过IDataBroker接口来获得IProvider接口。
  Delphi 4支持三种类型的远程数据模块:
  TremoteDataModule。这是一个支持双重接口的自动化服务器,这种类型的远程数据模块适合于使用DCOM、TCP/IP或OLEnterprise方式。
  TMTSDataModule。这也是一个支持双重接口的自动化服务器,用这种类型的远程数据模块创建的应用服务器是Active Library即动态链接库,适合于使用DCOM、TCP/IP或OLEnterprise方式。
  TcorbaDataModule。这是CORBA服务器,适用于与CORBA客户通讯。
  上述三种远程数据模块都可以作为容器,但只能放置非可视的构件。另外,远程数据模块上一般要放一个或几个TDataSetProvider或TProvider构件来提供IProvider接口 。
  远程数据模块上也可以放TDatabase构件和TSession构件。
3.1.6 MTS
  MTS是Microsoft Transaction Server的简称,是Microsoft为分布式环境下进行事务处理所设计的服务接口。使用TMTSDataModule类型的远程数据模块的优势是:
  MTS为应用服务器提供了基于角色的安全机制。每个客户都扮演着一种角色,决定了他们能否访问远程数据模块的接口。TMTSDataModule有一个函数叫IsCallerInRole,可以用来检查客户的角色,然后有条件地开放该角色所允许的功能。
  MTS提供了缓冲池的功能,它能把与数据库的连接放到池中,当一个客户不再需要连接时,另一个客户可以继续使用它,这样,应用服务器不必再次登录到远程数据库服务器。可能有的读者会想到,这个功能非常类似于TDatabase构件的KeepConnection属性。不过,要注意的是,如果用了TDatabase构件的话,KeepConnection属性最好设为False。
  MTS提供了强大的事务处理能力,它的“两阶段提交”技术使得应用程序能够跨服务器处理事务。
  可以用TMTSDataModule类型的远程数据模块实现一个MTS服务器,这个MTS服务器能够根据需要自动地激活或相反,换句话说,只有当远程数据模块接收到客户的连接请求时才创建模块的一个实例,这样能够最大程度地节省资源。
  由此可见,MTS服务器可以有两种工作方式,一是单实例方式,一个实例能够处理多个客户的请求,不过,如果客户较多的话,远程数据模块就成了瓶颈,制约着应用服务器的性能。二是多实例方式,每个客户请求连接时都会创建远程数据模块的一个实例,这样,几个客户就可以同时访问数据库而不需要排队。
  为了发挥MTS的上述优势,远程数据模块的实例必须做到与状态无关,而IProvider接口又依赖于状态信息,这就造成冲突。因此,TMTSDataModule类型的远程数据模块往往不用IProvider接口,而是自己创建一个接口来传递数据和申请更新。
  注意:使用MTS的时候,在远程数据模块的实例激活之前不能连接数据库。
3.1.7 IDataBroker接口和IProvider接口
  应用服务器上的远程数据模块支持IDataBroker接口,当客户程序与应用服务器连接以后,客户程序上的MIDAS连接构件就查找IDataBroker接口。
  IDataBroker接口只实现了一个方法叫GetProviderNames,调用这个方法可以获得一个列表,这个列表列出了应用服务器上的TDataSetProvider和TProvider构件。
  TClientDataSet的ProviderName属性可以指定其中一个TDataSetProvider或TProvider构件。当客户程序通过IDataBroker接口的GetProviderNames以及TClientDataSet的ProviderName属性指定了应用服务器上的一个TDataSetProvider或TProvider构件后,只要客户还在引用IProvider接口,远程数据模块的状态就应该保持,这与MTS的许多特点是有冲突的,也会与单实例的CORBA服务器发生冲突。
  客户程序与应用服务器之间通过IProvider接口交换数据,不过,大部分客户程序并不直接使用IProvider接口,而是通过TClientDataSet的属性和方法间接地使用IProvider接口。 不过,也可以通过Provider属性获得IProvider接口,然后直接访问IProvider接口。
  下面这个表列出了IProvider接口的属性和方法,同时列出了TProvider构件以及TClientDataSet构件中与之对应的属性和方法。

IProviderTProviderTClientDataset
ApplyUpdatesApplyUpdatesApplyUpdates
Constraints属性Constraints客户程序只能通过IProvider接口访问这个属性
DataDataData
DataRequestDataRequest客户程序只能通过IProvider接口访问这个方法
Get_ConstraintsConstraints客户程序只能通过IProvider接口访问这个方法
Get_DataGet_Data用于实现Data属性
GetMetaDataGetRecords(Count = 0)内部使用
GetRecordsGetRecords用于GetNextPacketResetReset内部使用
Set_ConstraintsConstraints客户程序只能通过IProvider接口访问这个属性
SetParamsSetParams用于Params属性

注意:IProvider接口的许多属性和方法依赖于远程数据模块的状态信息,正因为如此,在使用CORBA或MTS的应用程序中一般不要用IProvider接口。
3.2 选择连接方式
  在客户程序与应用服务器之间,Delphi 4提供了四种不同类型的连接方式或者说通讯协议,包括DCOM、TCP/IP、OLEnterprise和CORBA。这些不同的连接方式都各有利弊,到底选择哪种连接方式,取决于客户的数量、客户的分布情况以及怎样发布应用程序。
  DCOM是一种最直接的连接方式,它不需要专门的运行期软件支持。不过,Windows 95 不支持DCOM,除非安装了DCOM95程序。
  要使用MTS安全服务,最好使用DCOM连接方式。MTS的安全服务是基于角色的,当一个客户通过DCOM访问MTS时,DCOM会告诉MTS有关客户的信息,MTS据此来决定客户的角色。如果用其他连接方式,需要有专门的运行期软件支持,客户的调用首先被传递给这些运行期软件而不是MTS,MTS就不能尽快指派角色。
  TCP/IP连接方式的适合范围非常广泛,例如,如果客户程序要以ActiveForm的形式分布在Web上,最好采用TCP/IP连接方式,因为您无法肯定下载ActiveForm的计算机是否支持DCOM,而支持TCP/IP的环境是很普遍的。
  要使用TCP/IP连接方式,应用服务器端必须运行一个专门的运行期软件ScktSrver.exe或ScktSrvc.exe,其中,ScktSrvc.exe只适合于Windows NT,可以作为一个服务在后台运行。与DCOM连接方式不同的是,客户的请求首先传递给ScktSrver.exe或ScktSrvc.exe,然后再创建远程数据模块的实例,而不是由客户的调用直接创建远程数据模块的实例。客户程序上的MIDAS连接构件通过IProvider接口与ScktSrvr.exe or ScktSrvc.exe通讯。
  不过,客户程序很有可能在没有正常释放对IProvider 接口的引用之前出现异常,而TCP/IP连接方式无法检测到这种情况,更无法通知应用服务器,因此,有可能造成应用服务器上的资源被占用后得不到释放的后果。
  如果要在应用服务器端使用Business Object Broker,就要使用OLEnterprise连接方式。此时,应用服务器端和客户端都要安装OLEnterprise运行期软件。
  Delphi 4是目前唯一支持CORBA的开发工具。基于CORBA的客户程序和应用服务器可以与其他基于CORBA的应用程序无缝对接。要使用CORBA连接方式,需要ORB的支持,它提供了类似于Business Object Broker的功能。
3.3 创建应用服务器的一般步骤
  要创建一个多层Client/Server应用程序,首先要创建应用服务器,然后注册或安装应用服务器,只有应用服务器已注册并且正在运行的情况下,才能创建客户程序。对于客户程序来说,既可以在设计期连接应用服务器,也可以在运行期连接应用服务器。
  注意:如果客户程序与应用服务器不在同一个系统中,必须在客户计算机上注册或安装应用服务器,这样,在设计期就可以连接应用服务器。
  创建一个应用服务器与创建一个两层的数据库应用程序有些相似,主要的区别是,应用服务器需要提供IProvider接口,这一般是通过TDataSetProvider或TProvider构件提供的,也可以通过数据集构件如TTable的Provider属性提供。创建应用服务器的一般步骤是:
  第一步是使用"File"菜单上的"New Application"命令开始一个新项目,然后使用File菜单上的New命令,选取Multi页,如图3.1所示。
  选择一个远程数据模块。如果要创建一个COM自动化服务器,允许客户通过DCOM、TCP/IP、OLEnterprise等方式访问此服务器,选择RemoteMod。如果要创建一个允许客户通过MTS访问的Active Library,选择MTSData Module。如果要创建一个CORBA服务器,选择Corba Data。
  第二步是把一个数据集构件如TTable、TQuery或TStoredProc放到远程数据模块上,并进行有关设置,使得它们能访问远程的SQL数据库。尽量不要把TDatabase构件放到远程数据模块上,因为这可能引起名称冲突。如果实在要用TDatabase构件来连接SQL数据库,建议把TDatabase构件放到另一个数据模块上,然后引用这个数据模块的单元文件。
  第三步是把TDataSetProvider或TProvider构件放到远程数据模块上,有一个数据集构件,就要有一个TDataSetProvider或TProvider构件与之对应。然后,用鼠标右键单击TDataSetProvider或TProvider构件,在弹出的菜单中选择ExportFrom <Name> in Data Module命令,这是为了引出Provider接口,在类型库中注册。
  第四步是设置TDataSetProvider或TProvider构件的DataSet属性指定要访问的数据库,实际上就是第二步所放的数据集构件。
  第五步是编写代码,实现商业规则。当然,这一步远远不是几句话所能说清楚的。
  第六步是保存、编译、注册或安装应用服务器。
  如果使用DCOM、TCP/IP、OLEnterprise作为通讯协议,应用服务器就好像一个自动化服务器一样,必须像ActiveX或COM服务器那样注册。
  如果使用MTS,应用服务器是DLL而不是EXE,这时候不需要注册应用服务器,而要把这个DLL作为MTS对象安装到MTS包中。
  如果使用CORBA,可以不注册但最好注册。如果要使客户程序对服务器接口的调用在运行期是动态确定的,就要在接口库(Interface Repository)中安装服务器的接口。如果要使客户程序能自动激活应用服务器(如果还没有运行的话),应用服务器就必须用OAD(Object Activation Daemon)注册。
  第七步是如果应用服务器没有使用DCOM,您必须安装有关的运行期软件,因为其他连接方式需要这些运行期软件的支持。例如,对于TCP/IP来说,需要安装ScktSrvr.exe或ScktSrvc.exe,后者只能运行在Windows NT环境下。对于OLEnterprise来说,需要安装OLEnterprise运行期版本。对于CORBA来说,需要安装VisiBroker ORB。
3.4 远程数据模块
  应用服务器的关键部件是远程数据模块。Delphi 4支持三种类型的远程数据模块,分别是TRemoteDataModule、TMTSDataModule、TCorbaDataModule。
3.4.1 TRemoteDataModule
  要加入一个TRemoteDataModule类型的远程数据模块,使用“File”菜单上的“New”命令,选取“Multitier”页,双击“Remote Data Module”图标,弹出“Remote Data Module Wizard”对话框,如图3.2所示。
  在“Class Name”框内键入远程数据模块的类名,不必以T打头。Delphi 4将以此名生成一个TRemoteDataModule的派生类,并以此名生成有关接口。例如,假如在“Class Name”框内键入“MyDataServer”, 远程数据模块的类名就是TMyDataServer,它所实现的接口叫IMyDataServer,其祖先接口是IDataBroker。
  在“Threading Model”框内选择一种线程模式。可以选“Single-threaded”、“Apartment-threaded”、“Free-threaded”或者“Both”。
  在“Instancing”框内选择是否根据客户的请求生成远程数据模块的多个实例,可以选“Single instance”或“Multiple instance”。
3.4.2 TMTSDataModule
  要加入一个TMTSDataModule类型的远程数据模块,使用“File”菜单上的“New”命令,选择“Multitier”页,双击“MTS Data Module”图标,弹出“MTSData Module Wizard”对话框,如图3.3所示。
  图3.3 MTS Data Module对话框
  在“Class Name”框内键入远程数据模块的类名,不必以T打头。Delphi 4将以此名生成一个TMTSDataModule的派生类,并以此名生成有关接口。例如, 假设在“Class Name”框内键入“MyDataServer”, 远程数据模块的类名就是TMyDataServer,它所实现的接口叫IMyDataServer,其祖先接口是IDataBroker。
  对于TMTSDataModule类型的远程数据模块来说,必须在“ThreadingModel”框内选择一种线程模式。可以选“Single”、“Apartment”或者“Both”。在“Transaction Attributes”框内选择事务属性:
  如选择“Requires a transaction”,每当客户访问远程数据模块的接口时,都与当前的事务是相关的。客户不可能在事务中再申请一个新的事务。
  如选择“Requires a new transaction”,每当客户访问远程数据模块的接口时,都自动开始一个新的事务。如选择“Supports transactions”,远程数据模块可以用在事务的环境中,客户访问远程数据模块的接口时必须申请一个新的事务。
  如选择“Does not support transactions”,远程数据模块不能用在事务的环境中。
  注意:MTS对象只能加入到ActiveX项目中,如果试图在一个EXE项目中加入TMTSDataModule类型的远程数据模块,Delphi 4会显示一个提示框,如图3.4所示。
  图3.4 一个提示框
3.4.3 TCORBADataModule
  要加入一个TCorbaDataModule类型的远程数据模块,使用“File”菜单上的“New”命令,选取“Multitier”页,双击“CORBA Data Module”图标,弹出“CORBA Data Module Wizard”对话框,如图3.5所示。
  图3.5 CORBA Data Module对话框
  在“Class Name”框内键入远程数据模块的类名,不必以T打头。Delphi 4将以此名生成一个TCorbaDataModule的派生类,并以此名生成有关接口。例如,假设在“Class Name”框内键入“MyDataServer”, 远程数据模块的类名就是TMyDataServer,它所实现的接口叫IMyDataServer,其祖先接口是IDataBroker。
  在“Instancing”框内指定应用服务器怎样创建远程数据模块的实例,可以选“Shared Instance”或者“Instance-Per-Client”。
  如果选“Shared Instance”,应用服务器只创建远程数据模块的一个实例来处理所有客户的请求,因此,远程数据模块必须与状态无关,换句话说,就是不能使用IProvider接口。
  如果选“Instance-Per-Client”,每当一个客户试图连接时,远程数据模块都会生成一个实例。只要客户与应用服务器的连接没有断开,远程数据模块的实例就一直存在。这种模式下,允许使用IProvider接口。唯一要考虑的问题是,客户程序有可能意外终止,导致没有正常地断开与应用服务器的连接。应用服务器为了避免不必要的资源浪费,可以定期地检查客户是否正在运行,如没有,就手工把远程数据模块的实例删掉。
  在“Threading Model”框内选择一种线程模式。可以选“Single-threaded”、“Multi-threaded”。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值