(连接篇)
Delphi 的MIDAS出来了这么多年终于有改进的版本了,COM-FREE的DataSnap 2009真是清爽了很多,DataSnap 2009 除了不支持回调和Intercept组件以外 其它的该有的都有了 而且还有很多强大的特性;
第一篇就先写点DataSnap 2009连接方面可能要用到的东西,以后再继续写写关于生命周期的管理 对象池的应用 以及远程管理 远程方法调用等方面的东西吧。
首先 建立个DataSnap 2009的服务器工程,一共用到三个组件:
DSServer 服务配置组件 用于绑定其它的组件;
DSServerClass 可以看作是一个类的工厂 用于导出需要远程调用的服务端模块;
DSTCPServerTransport 传输组件 这里使用的是indy的tcpserver;
将DSServerClass和DSTCPServerTransport 的Server设置成DSServer就可以了,客户端连接和断开连接时会触发DSServer的两个事件OnConnect和OnDisConnect,参数为 TDSConnectEventObject。
我们看下该类的定义
TDSConnectEventObject = class(TDSEventObject) public constructor Create(const ADbxContext: TDBXContext; const AServer: TDSCustomServer; const ATransport: TDSServerTransport; const AChannelInfo: TDBXChannelInfo; const ADbxConnection: TDBXConnection; const AConnectProperties: TDBXProperties); private FConnectProperties: TDBXProperties; FChannelInfo: TDBXChannelInfo; public property ConnectProperties: TDBXProperties read FConnectProperties write FConnectProperties; property ChannelInfo: TDBXChannelInfo read FChannelInfo; end;
我们可以看到其中包含了两个属性ConnectProperties 和ChannelInfo:
ConnectProperties 包含了客户端连接所传递的参数 Params 也就是一个TStrings的内容;
ChannelInfo 里面有个很重的属性就是它的ID 其实是TIdTCPConnection对象的ID 所以我们可以直接强制转换成TIdTCPConnection;
然后建立个DataSnap 2009的客户端工程,由于使用的DbExpress框架客户端连接用的是TSQLConnection组件,只要把Driver设置成Datasnap即可。连接的服务器地址通过HostName和Port来进行设定,下面我们就实现个简单的DEMO 客户端通过用户名和密码连接服务端 如果密码不争取服务端则断开连接。
客户端主要函数
procedure TMainForm.ConnectClick(Sender: TObject); begin SQLConnection.Params.Values['User_Name'] := UserName.Text; SQLConnection.Params.Values['PassWord'] := Password.Text; try SQLConnection.Open; Connect.Enabled := False; DisConnect.Enabled := True; except ShowMessage('连接服务器失败!'); end; end; procedure TMainForm.DisConnectClick(Sender: TObject); begin SQLConnection.Close; Connect.Enabled := True; DisConnect.Enabled := False; end;
服务端主要函数
procedure TMainForm.DSServerConnect(DSConnectEventObject: TDSConnectEventObject); const SRemoteConnected = '远程客户端连接 %s:%d'; SUserNameAndPassword = '用户名: %s 密码: %s'; SAuthSuccess = '用户名密码认证成功'; SAuthFailed = '用户名密码认证失败'; var Conn: TIdTCPConnection; begin Conn := TIdTCPConnection(DSConnectEventObject.ChannelInfo.Id); LogMessage(Memo, Format(SRemoteConnected, [Conn.Socket.Binding.PeerIP, Conn.Socket.Binding.PeerPort])); with DSConnectEventObject.ConnectProperties do begin LogMessage(Memo, Format(SUserNameAndPassword, [Values['User_Name'], Values['PassWord']])); if (Values['User_Name'] = 'Admin') and (Values['PassWord'] = '123456') then LogMessage(Memo, SAuthSuccess) else begin LogMessage(Memo, SAuthFailed); Conn.Disconnect; end; end; end; procedure TMainForm.DSServerDisconnect(DSConnectEventObject: TDSConnectEventObject); const SRemoteDisConnected = '远程客户端断开连接 %s:%d'; var Conn: TIdTCPConnection; begin Conn := TIdTCPConnection(DSConnectEventObject.ChannelInfo.Id); LogMessage(Memo, Format(SRemoteDisConnected, [Conn.Socket.Binding.PeerIP, Conn.Socket.Binding.PeerPort])); end;
注意:OnConnect事件中还可以使用另外一种方式拒绝客户端连接,在代码中抛出个异常即可 在客户端会捕捉到一个TDBXError的异常 显示'Remote error ' 加上异常显示的消息。
效果图如下: