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
我們看下該類的定義
1 TDSConnectEventObject = class(TDSEventObject)
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 客戶端通過用戶名和密碼連接服務端 如果密碼不爭取服務端則斷開連接
客戶端主要函數
1 procedure TMainForm.ConnectClick(Sender: TObject);
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;
服務端主要函數
1 procedure TMainForm.DSServerConnect(DSConnectEventObject: TDSConnectEventObject);
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 ' 加上異常顯示的消息。
效果圖如下:
圖片看不清楚?請點擊這裡查看原圖(大圖)。