Delphi 2010 DataSnap白皮书1
2010-04-07 11:25
在这个白页中我们将讲解Delphi2010 DataSnap架构新的特性和功能. 1. DATASNAP 历史
作为MIDAS起始于Delphi3,Delphi4是MIDAS II,Delphi5中是MIDASIII,而后基于COM远程数据模块方式使
用TCP/IP,HTTP,(D)COM构建出强大的通讯能力.从Delphi6开始改名为DataSnap,直到D2007这个框架一直在使
用.D2009重新架构了DataSnap—移除COM依赖,使用TCP/IP以更轻量级的方式生成远程服务对象和客户端连接
能力.同时提供了与Delphi Prism2009开发的.NET程序通讯的功能.
Delphi2010中构建于D2009架构之上,并对此架构做了进一步的扩展,包括使用两个向导来创建新的
部署目标(VCL窗体,Window服务,控制台及面向Web的ISAPI,CGI或Web App Debugger).HTTP(S)传输协
议,HTTP验证,客户端回调函数,REST和JSON的支持,及使用过滤器来支持压缩和解压缩.
1.1 DATASNAP范例数据位置
本白页中我建议您使用Demo和范例来学习.虽然Delphi支持很多数据库系统,使用DBX4,ADO dbGo,或
其他数据存取技术,为了演示方便我这里使用DBX4来操作BlackfishSQL的employee.jds数据库.见
[ C:\\Documents and Settings\\All Users\\Documents\\RAD
Studio\\7.0\\Demos\\database\\databases\\BlackfishSQL\\employee.jds].在截图中可以看到我使用的
是Windows Vista或Win7操作系统,使用Windows Server 2008 Web编辑器来部署DataSnap ISAPI服务. 2. DATASNAP目标:如何获取数据
DataSnap2010支持三种不同的Windows方式:VCL窗体,Windows服务和控制台应用程序.本节中我们
将讨论他们的好处,不同和每种方式最适合在什么情况下使用.
下面会创建一个DataSnap服务端和客户端,我们将讲解
TDSServer,TDSServerClass,TDSTCPServerTransport,TDSHTTPService,TDSHTTPWebDispatcher和
TDSHTTPServiceAuthenticationManager组件,以及自定义的服务方法和
TDSServerModule类.
将讨论不同的传输协议(TCP,HTTP)的好处及传输效率.并讨论DataSnap服务对象的不同生命期选项
(Server,Session,Invocation),及他们的效率和使用的建议.最后,讨论部署. 2.1. DATASNAP 服务端范例
在Object Repository中有两个不同的DataSnap服务向导:一个是生成基于Windows的Datasnap服务
项目,一个是生成基于WebBroker的DataSnap服务项目(需要部署到IIS或Apache).我们将会演示.
启动了Delphi2010,点击File.New.Other,你会在Object Repository中看到DataSnap服务向导中
显示的三个图标:DataSnap Server,DataSnap WebBroker Server,和Server Module.
双击第一个(后面的两个在下面的小结中讲解),弹出如下对话框:
界面中第一部分是控制项目类型的.默认可以生成可视化的带有主窗体的VCL窗体应用程序.第二个
选项是创建控制台应用程序,生成一个控制台窗口—可以用来输出请求应答信息(用Writeln语句输出
服务应用程序正在做什么).这两种方式都是为了做范例或最初部署,很少用于最终部署.由于
DataSnap架构不再基于COM,客户端将不能使服务端启动.因此为了响应客户端的请求,DataSnap服务
端应该一直在运行.如果你希望应用7X24小时全天候运行,DataSnap服务端必须同时也在运行中.对应
VCL窗体或控制台应用程序,需要一个账户登录到Windows中后才能启动DataSnap服务,背离了这种要
求.第三者选择在这时最适合:一个Windows服务应用程序,安装后配置成为自动启动,当计算机启动后
将自动运行(不需要账户登录).服务应用程序不会弹出界面,很难调试Bug.然而,为了整合这三种的优
势,我将用几分钟创建一个项目组,包括VCL窗体应用程序的DataSnap服务,控制台DataSnap服务,及
Windows服务Datasnap服务,都共享同一个自定义的服务方法,这样就可以开发一个Datasnap服务应用
程序,在需要的时候编译出三个不同类型的部署方式.
第二部分是选择使用的Datasnap服务的通讯协议.和DanaSnap2009相比,我们可
以看到多了一个
HTTP通讯,及HTTP验证.为了更加灵活,这里建议选择全部选项,我们可以同时使用TCP/IP,HTTP,及使
用HTTP引入的HTTP验证.
第三部分已经为我们配置好了,如果我们要提供一个服务方法类,我们可以选择它的基
类:TPersistent,TDataModule或TDSServerModule.推荐使用最后的一个选项,可使用RTTI来启动执行
函数 (也可能你觉得使用TDataModule更合适—不操作数据库,或不使用其他非可视控件,这时使用 TPersitent也够用了).
现在是从DSServer.pas中贴出来的一小段代码,来说明TDSServerModule和 TProviderDataModule(也是继承于TDataModule)之间的关系. TDSServerModuleBase = class(TProviderDataModule) public
procedure BeforeDestruction; override; destructor Destroy; override; end;
{$MethodInfo ON}
TDSServerModule = class(TDSServerModuleBase) end;
{$MethodInfo OFF}
当无法确定时就使用TDSServerModule选项作为基类. 2.1.1. 创建多目标项目组-- VCL 窗体项目
如上面所说,这里创建多目标的Datasnap服务项目组.首先创建一个VCL窗体应用程序作为Datasnap
服务,选择所有的通讯协议.
默认创建了一个叫做Project1.dproj的项目,并带有三个单元文
件,ServerContainerUnit1.pas,ServerMethodUnit1.pas和Unit1.pas.首先File.Save Project As保
存项目,并输入有实际意义的文件名称.将Unit1.pas保存为
MainForm.pas,ServerMethodsUnit1.pas
保存为ServerMethodsUnitDemo.pas文件,保存Project1.dproj为DataSnapServer.dproj.
稍后我们将向项目组添加控制台应用程序和Window服务应用程序.首先我们来检查一下项目,并编
译工程.如果你编译DataSnapServer项目,将会出现一个错误信息(由于我们将 ServerMethodsUnit1.pas改名所致).错误原因是由于ServerContainerUnitDemo.pas单元中的
Implementation部分引用了ServerMethodsUnit1.pas单元.为了修复这个冲突,修改引用单元的文件
名称,从新编译.这是发现在第37行出现错误,使用了ServerMethodsUnit1中的TServerMethods1类型.
修改ServerMethodsUnit1为ServerMethodsUnitDemo.这时可以正确的编译项目了.
ServerContainerUnitDemo的引用部分应该向下面代码所示: implementation uses
Windows, ServerMethodsUnitDemo; {$R *.dfm}
procedure TServerContainer1.DSServerClass1GetClass(
DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass); begin
PersistentClass := ServerMethodsUnitDemo.TServerMethods1; end; end.
2.1.1.1. SERVERCONTAINERUNITDEMO
打开ServerContainerUnitDemo单元,将会看到不少于五个组件:一个TDSServer,一个
TDSServerClass,一个TDSTCPServerTransport(用于TCP/IP通讯),一个TDSHTTPService(用于HTTP
通讯),一个TDSHTTPServiceAuthenticationManager组件(用于HTTP验证).
前面两个一直会存在,其他的三个则是根据选择的通讯协议生成的. 2.1.1.1.1. TDSSERVER
TDSServer组件只有四个属性,AutoStart,HideDSAdmin,Name和Tag.AutoStart属性默认设置为
True,意味着在窗体创建后自动启动DataSnap服务.如果将AutoStart设置为False,需要手动调用
Start方法启动服务,并调用Stop方法停止服务.可以调用Started方法验证DataSnap服务是否已经 启动.
HideAdmin属性默认设置为False.如果设置为True,连接到DataSnap服务的客户端将无法调用
Datasnap服务中的TDSAdmin类的内置方法.TDSAdmin不是一个真正的类,我们可以调用的TDSAdmin
方法定义在DSNames单元: TDSAdminMethods = class public
const CreateServerClasses = 'DSAdmin.CreateServerClasses'; const CreateServerMethods = 'DSAdmin.CreateServerMethods'; const FindClasses = 'DSAdmin.FindClasses'; const FindMethods = 'DSAdmin.FindMethods'; const FindPackages = 'DSAdmin.FindPackages'; const GetPlatformName = 'DSAdmin.GetPlatformName'; const GetServerClasses = 'DSAdmin.GetServerClasses'; const GetServerMethods = 'DSAdmin.GetServerMethods';
const GetServerMethodParameters = 'DSAdmin.GetServerMethodParameters'; const DropServerClasses = 'DSAdmin.DropServerClasses'; const DropServerMethods = 'DSAdmin.DropServerMethods'; const GetDatabaseConnectionProperties =