DataSnap基础

2020-06-05 11:11

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 7操作系统,使用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 = \const CreateServerMethods = \const FindClasses = \const FindMethods = \const FindPackages = \

const GetPlatformName = \const GetServerClasses = \const GetServerMethods = \

const GetServerMethodParameters = \const DropServerClasses = \const DropServerMethods = \

const GetDatabaseConnectionProperties = \end;

TDSServer组件有五个事件:OnConnect,OnDisconnect,OnError,OnPrepare和OnTrace.我们可以 实现这五个事件来响应不同的情况,例如向日志文件中写入日志.

OnConnect,OnDisconnect,OnError和OnPrepare事件有一个继承于TDSEventObject的参数,包含了DxContext,传输,服务和DbxConnection组件的属性,在OnConnect和OnDisconnect事件中TDSConnectEventObject类型还包含了ConnectionProperties和ChannelInfo属性.

TDSConnectEventObject也包括了由错误引起的异常, TDSConnectEventObject还包括了我们要使用的MethodAlias和ServerClass属性.OnTrace事件有一个TDBXTraceInfo类型的参数.注意由于这个OnTrace事件处理程序也会包含一些代码错误,如TDBXTraceInfo和CBRType是编译器未知的.为了解决这个问题,我们需要引用DBXCommon单元(为识别TDBXTraceInfo类型)和DBComonTypes单元(为识别CBRType类型).在OnConnect事件处理中,我们可以通过ChannelInfo来查看连接信息,例如(使用自定义的函数LogInfo向日志文件中写入信息): procedure TServerContainer1.DSServer1Connect( DSConnectEventObject: TDSConnectEventObject); begin

LogInfo(\end;

在OnTrace事件处理程序中我们可以使用TraceInfo.Message中的信息记录服务端正在做什么. function TServerContainer1.DSServer1Trace(TraceInfo: TDBXTraceInfo): CBRType; begin

LogInfo(\LogInfo(\

Result := cbrUSEDEF; // take default action end;

注意,在客户端也可以使用连接到TSQLConnection组件的TSQLMonitor组件来跟踪DataSnap服务端和客户端之间的通讯(在创建这个DataSnap服务的客户端时讲解).

一个跟踪日志输出如下所示: 17:05:55.492 Trace

17:05:55.496 read 136 bytes:{\

{\\

17:05:55.499 Prepare

如你所见,TraceInfo.Message中包括了传输信息的字节数和被调用的方法名称等信息. 2.1.1.1.2. TDSSERVERCLASS

TDSServerClass组件将服务端特定的类发布给远程客户端(使用动态方法调用).

TDSServerClass组件有一个Server属性指向TDSServer组件.其他除了Name和Tag外的重要属性是LifeCycle.默认是Session,但是也可设置为Server或Invocation.从长到短,Server,Session

和Invocation的意思是一个类的实例在服务端的生命周期为整个服务,一个DataSnap会话或一次方法调用.Session表示每个连接将获取其自己的服务类实例.如果将其改为Invocation,将会得到一个无状态的服务类—可用于部署CGI Web服务应用程序(其也是无状态的,每个请求都进行加载卸载).将LifeCycle改为Server,则所有的连接请求使用一个服务类实例.这可以用于计算请求数量,但是必须自己保证线程安全.

TDSServerClass有四个事件:OnCreateInstance,OnDestroyInstance(当实例创建和注销时触

发).OnGetClass和OnPrepare.OnPrepare事件可用于准备服务方法.使用D2009或使用D2010手动向容器中添加TDSServerClass时,OnGetClass事件必须由我们自己实现,以便于指定一个可远程调用的类.在D2010的向导中,已经自动为我们实现了OnGetClass事件,如下:

procedure TServerContainer1.DSServerClass1GetClass(

DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass); begin

PersistentClass := ServerMethodsUnitDemo.TServerMethods1; end;

注意:当我们重命名了自动生成的代码单元ServerMethodsUnit1为 ServerContainerUnitDemo.pas后必须修改这里. 2.1.1.1.3. TDSTCPSERVERTRANSPORT

TDSTCPServerTransport组件负责在DataSnap服务端和客户端进行通讯,使用TCP/IP协议. TDSTCPServerTransport组件有五个重要的属性:BufferKBSize,Filters(D2010新特 性),MaxThreads,PoolSize,Port和Server.

BufferKBSize属性指定通讯缓冲区大小,默认设置为32KB.Filters属性可以包含一个传输过滤

器集合,将在第四节讲解.MaxThreads属性定义最大线程数(默认为0不限制).PoolSize可用于连接池(如果修改了这里,也需要相应的修改DataSnap客户端).

Server属性指向TDSServer组件.TDSTCPServerTransport组件没有事件.

2.1.1.1.4. TDSHTTPSERVICE

TDSHTTPService组件负责使用HTTP协议组织DataSnap服务端和客户端通讯. TDSHTTPService组件有十个属性(除了Name和

Tag):Active,AuthenticationManager,DSHostName,DSPort,Filters,HttpPort,Name,RESTContext,Server,和只读的ServerSoftware属性.

Active属性指定DSHTTPService开始侦听请求.可以在设计时设置,但是这会影响DataSnap服务在运行时启动(由于DSHTTPService组件侦听了同一个端口—在设计时启动侦听,在运行时就不能再启动一个侦听了).最好的方式在在TServerContainer的OnCreate事件中激活TDSHTTPService: procedure TServerContainer1.DataModuleCreate(Sender: TObject); begin

DSHTTPService1.Active := True; end;

AuthenticationManager属性用于定义处理HTTP验证的管理组件,这里指向了 TDSHTTPServiceAuthenticationManager组件.这个组件在下节详述.

DSHostName和DSPort属性用于定义DataSnap服务端连接,但只有在没有指定Server属性时生效.

通常都是使用Server属性.

Filters属性可以包含一系列传输过滤器,在第四节详述.

HttpPort属性定义DSHTTPService组件侦听的特定端口以响应连接.注意这个属性默认是80端口,通常在发布时必须做修改(IIS等Web服务已占用了80端口).

RESTContext属性指定REST上下文URL,这样就可以以REST服务的方式调用DataSnap服务.默认,RESTContext属性设置为rest,我们可以用http://localhost/datasnap/rest/...来调用服务. 在第六节详述REST,JSON和客户端回调函数.

最后,Server属性指向同一个容器中的TDSServer组件.如果没有指定Server属性,也可以使用

DSHostName和DSPort属性连接到使用TCP的DataSnap服务.当设置了Server属性,DSHostName和DSport属性失效. TDSHTTPService组件有五个事件:四个是REST相关的,一个是跟踪事件,REST相关事件将在第六节详述. OnTrace事件可用于跟踪对DSHTTPService组件的调用,例如:

procedure TServerContainer1.DSHTTPService1Trace(Sender: TObject; AContext: TDSHTTPContext; ARequest: TDSHTTPRequest; AResponse: TDSHTTPResponse); begin

LogInfo(\LogInfo(\

LogInfo(\end;

注意HTTP跟踪信息只有当客户端使用HTTP连接到服务端是才会触发(默认使用TCP/IP协议).

跟踪输出如下所示:

17:05:55.398 HTTP Trace TDSHTTPContextIndy 17:05:55.400 /datasnap/tunnel 17:05:55.403 OK

从中可见,AContext设置为TDSHTTPContextIndy,ARequest设置为/DataSnap/tunnel,AResponse设置为OK.

2.1.1.1.5. TDSHTTPSERVICEAUTHENTICATIONMANAGER

当选中HTTP通讯协议的验证复选框后,TDSHTTPServiceAuthenticationManager组件将自动出现在服务容器中.也可手动添加到服务容器中,当然TDSHTTPService组件的AuthenticationManager属性必须指向TDSHTTPServiceAuthenticationManager组件.

TDSHTTPServiceAuthenticationManager组件有一个事件:OnHTTPAuthenticate事件,可以验证 Datasnap客户端到服务端连接的HTTP信息.

procedure TServerContainer1.DSHTTPServiceAuthenticationManager1HTTPAuthenticate( Sender: TObject; const Protocol, Context, User, Password: string; var valid: Boolean); begin

if (User = \valid := True else

valid := False end;

当然,你可以使用数据库技术来扩展验证方式.客户端最好使用HTTPS方式将用户名和密码等HTTP验证信息发送到服务端,所以我希望易博龙可以在现有HTTP和TCP/IP基础上在添加一个HTTPS协议.

HTTPS可以确保连接安全和数据包加密, 数据包被窃取也不会泄露用户和密码信息.可与你所在域的ISP或Web管理员协商是否有可能使用HTTPS—--强烈推荐(如我使用的 是https://www.bobswart.hl/).


DataSnap基础.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:食品物性学习题(附答案)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: