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
我们看下该类的定义
2 public
3 constructor Create( const ADbxContext: TDBXContext; const AServer: TDSCustomServer; const ATransport: TDSServerTransport; const AChannelInfo: TDBXChannelInfo; const ADbxConnection: TDBXConnection; const AConnectProperties: TDBXProperties);
4 private
5 FConnectProperties: TDBXProperties;
6 FChannelInfo: TDBXChannelInfo;
7 public
8 property ConnectProperties: TDBXProperties read FConnectProperties write FConnectProperties;
9 property ChannelInfo: TDBXChannelInfo read FChannelInfo;
10 end ;
我们可以看到其中包含了两个属性ConnectProperties和ChannelInfo
ConnectProperties包含了客户端连接所传递的参数 Params 也就是一个TStrings的内容
ChannelInfo里面有个很重的属性就是它的ID 其实是TIdTCPConnection对象的ID 所以我们可以直接强制转换成TIdTCPConnection
然后 建立个DataSnap 2009的客户端工程
由于使用的DbExpress框架 客户端连接用的是TSQLConnection组件
只要把Driver设置成Datasnap即可
连接的服务器地址通过HostName和Port来进行设定
下面我们就实现个简单的DEMO 客户端通过用户名和密码连接服务端 如果密码不争取服务端则断开连接
客户端主要函数
2 begin
3 SQLConnection.Params.Values[ ' User_Name ' ] : = UserName.Text;
4 SQLConnection.Params.Values[ ' PassWord ' ] : = Password.Text;
5 try
6 SQLConnection.Open;
7 Connect.Enabled : = False;
8 DisConnect.Enabled : = True;
9 except
10 ShowMessage( ' 连接服务器失败! ' );
11 end ;
12 end ;
13
14 procedure TMainForm.DisConnectClick(Sender: TObject);
15 begin
16 SQLConnection.Close;
17 Connect.Enabled : = True;
18 DisConnect.Enabled : = False;
19 end ;
服务端主要函数
2 const
3 SRemoteConnected = ' 远程客户端连接 %s:%d ' ;
4 SUserNameAndPassword = ' 用户名: %s 密码: %s ' ;
5 SAuthSuccess = ' 用户名密码认证成功 ' ;
6 SAuthFailed = ' 用户名密码认证失败 ' ;
7 var
8 Conn: TIdTCPConnection;
9 begin
10 Conn : = TIdTCPConnection(DSConnectEventObject.ChannelInfo.Id);
11 LogMessage(Memo, Format(SRemoteConnected, [Conn.Socket.Binding.PeerIP, Conn.Socket.Binding.PeerPort]));
12 with DSConnectEventObject.ConnectProperties do
13 begin
14 LogMessage(Memo, Format(SUserNameAndPassword, [Values[ ' User_Name ' ], Values[ ' PassWord ' ]]));
15 if (Values[ ' User_Name ' ] = ' Admin ' ) and (Values[ ' PassWord ' ] = ' 123456 ' ) then
16 LogMessage(Memo, SAuthSuccess)
17 else
18 begin
19 LogMessage(Memo, SAuthFailed);
20 Conn.Disconnect;
21 end ;
22 end ;
23 end ;
24
25 procedure TMainForm.DSServerDisconnect(DSConnectEventObject: TDSConnectEventObject);
26 const
27 SRemoteDisConnected = ' 远程客户端断开连接 %s:%d ' ;
28 var
29 Conn: TIdTCPConnection;
30 begin
31 Conn : = TIdTCPConnection(DSConnectEventObject.ChannelInfo.Id);
32 LogMessage(Memo, Format(SRemoteDisConnected, [Conn.Socket.Binding.PeerIP, Conn.Socket.Binding.PeerPort]));
33 end ;
注意:OnConnect事件中还可以使用另外一种方式拒绝客户端连接
在代码中抛出个异常即可 在客户端会捕捉到一个TDBXError的异常 显示'Remote error ' 加上异常显示的消息。
效果图如下:
附上DEMO源码 DataSnapDemo_1.rar