DataSnap提供了實作C/S應用的技術。
一、實作一個基本的DataSnap服務端。
1. 實作DataSnap服務端的幾個基本控件:TDSServer控件、TDSServerClass控件和TDSTCPServerTransport控件。
TDSServer控件:DataSnap服務端程式的邏輯核心,用來啟動和停止服務。AutoStart屬性預設設定為true,程式一運作就自動啟動服務。
TDSServerClass控件:代表一個伺服器類,服務端的方法由它來引出供用戶端遠端調用。DataSnap Server自動建立和銷毀一個伺服器類的執行個體。這個執行個體的生命周期受TDSServerClass的LifeCycle屬性控制。LifeCycle有三種選擇:Server, Session 和 Invocation.
- Server模式: 為所有的用戶端隻建立一個執行個體,這種模式下要注意線程安全,因為隻有一個執行個體來同時處理多個用戶端請求。
- Sessionm模式:這是LifeCycle的預設設定,為每一個連接配接到服務端的用戶端建立一個伺服器執行個體。
- Invocation模式:用戶端的每一次連接配接(伺服器方法調用)都回建立一個伺服器執行個體。
(為了讓用戶端和服務端進行通訊,引入了TDSTCPServerTransport控件. 當然也可以通過HTTP協定來通訊。)
TDSTCPServerTransport控件:實作一個多線程的TCP伺服器,多線程監聽用戶端連接配接。
2. 服務端實作步驟:
(1). File > New > VCL Forms Application - Delphi, 加入三個控件,TDSServer控件、TDSServerClass控件和TDSTCPServerTransport控件。将TDSServerClass和TDSTCPServerTransport的Server屬性都設定成TDSServer控件的名字,比如DSServer1。
(2). File > New > Unit - Delphi生成一個新的Delphi檔案,存為MyClass,代碼如下:
unit MyClass;
interface
uses Classes;
Type
{$METHODINFO ON}
TMyClass = class(TComponent)
function Sum(const A,B: Double):Double;
end;
{$METHODINFO OFF}
implementation
function TMyClass.Sum(const A: Double; const B: Double): Double;
begin
result := A + B;
end;
end.
代碼中的{$METHODINFO ON}會為DataSnap Server産生運作時資訊,這是必須的,而不僅僅是一個注釋。
(3). 将MyClass單元引入伺服器主程式單元,并在TDSServerClass控件的GetClass事件中引入MyClass。
procedure TForm2.DSServerClass1GetClass(DSServerClass: TDSServerClass;
var PersistentClass: TPersistentClass);
begin
PersistentClass := TMyClass;
end;
DataSnap架構最重要的一個概念就是将一個類的引用賦給PersistentClass,而不是一個Object。
一個簡單的但是完整的伺服器程式建立完畢。
二、實作一個基本的DataSnap用戶端。
在實作一個用戶端前,先編譯并運作上面完成的服務端。
1. File > New > VCL Forms Application - Delphi, 加入幾個編輯和顯示控件,如下圖:
2. 設定SQLConnection1的Driver為DataSnap,因為現在服務端和用戶端都在同一台機器上,是以DataSnap下面的參數可以選用預設的參數。
3. 勾選SQLConnection1的Connected為True, SQLConnection1會自動連接配接到已經在運作的服務端上,右鍵點選SQLConnection1控件,選擇Generate DataSnap Client Classes. 程式會自動産生一個從服務端導出的Delphi單元檔案,檔案描述了要遠端調用的服務端類及函數。這裡儲存為MyDSClient.Pas,裡面導入了服務端的類MyClass.
4. 用戶端主程式引入這個單元檔案,并在Calculate按鈕的onclick事件中遠端調用服務端的函數Sum.
procedure TClientForm.btnExecuteClick(Sender: TObject);
var
Temp: TMyClassClient;
A,B: Double;
begin
Temp := TMyClassClient.Create(SQLConnection1.DBXConnection);
try
A := StrToFloat(edA.Text);
B := StrToFloat(edB.Text);
edResult.Text := floatToStr(Temp.Sum(A,B));
finally
Temp.Free;
end;
end;
運作用戶端并測試。