Tiburon遊記3 動手建立一個DataSnap JSON伺服器吧

Tiburon遊記3 動手建立一個DataSnap JSON伺服器吧

也許讓我們先動手用Tiburon實作一個DataSnap JSON分散式架構再搭配前面說明的觀唸的話,各位將會更加瞭解Tiburon把這些強大的功能做得多麼的方便。
DataSnap新的JSON分散式架構可以有許多不同的型態,更可以結合資料庫和Web應用程式,不過在一開始讓我們先學習如何建立最簡單的JSON分散式架構,下面是我們即將實作的JSON分散式架構的簡單說明:
1.    建立一個分散式JSON伺服器,在JSON伺服器中提供伺服端的服務方法讓用戶端`可以呼叫使用
2.    建立一個DataSnap用戶端應用程式,藉由TCP + JSON架構呼叫分散式JSON伺服器提供的服務
在步驟1中我們將看到Tiburon新的Reflect功能如何把伺服端的服務方法輸出,而步驟2我們則可以看到Tiburon的DataSnap元件如何在原有的元件中加入可以處理JSON分散式架構的功能。

步驟 1 – 建立分散式JSON伺服器

要建立分散式JSON伺服器非常的簡單,它的步驟如下:
1.    建立一個VCL Form的應用程式
2.    在主表單中加入TDSServer元件,TDSServer元件負責JSON伺服器和用戶端的生命週期管理,並且提供了許多管理的機制。
3.    在主表單中加入TDSTCPServerTransport元件,TDSTCPServerTransport元件使用Indy做為底層TCP通訊元 件,TDSTCPServerTransport元件內定上使用211通信埠做為和用戶端連結的通信埠,它並且可以提供通訊池的功能以便有效率的使用伺服 器的資源
4.    在主表單中加入TDSServerClass元件,TDSServerClass元件可以把伺服器中的類別輸出給用戶端呼叫,或是把資料模組,遠端資料模 組中的方法輸出給用戶端呼叫-。TDSServerClass元件藉由Tiburon新強化的RTTI和Reflect程式單元中的功能以達成這種能力。 對於需要輸出服務給用戶端的類別,資料模組或是遠端資料模組,必須使用新的編譯器指令{$MethodInfo ON}和{$MethodInfo OFF}包圍類別宣告。
5.    連結TDSTCPServerTransport元件到TDSServer元件,此時主表單應該看起來如下:

 http://blufiles.storage.live.com/y1pvI3feAq-mPlOnHSFEKzb0u0DQ5AoxWtMrWZOPYFJqqgh3bXtuyRb4tscQz3rNfpq
現在在這個範例VCL Form的應用程式專案中加入一個新的程式單元,並且撰寫如下的程式碼:
unit uServerMethod;

interface

uses Sysutils, classes;

type

{$MethodInfo ON}
  TServerMethodClass = class(TPersistent)
  public
    function Hello(const Name: string): string;
  end;
{$MethodInfo OFF}

implementation

{ TServerMethodClass }

function TServerMethodClass.Hello(const Name: string): string;
begin
  Result := 'Hello ' + Name;
end;

end.
各 位可以看到上面宣告了一個TServerMethodClass,它必須從TPersistent類別繼承下來,由於它需要函式Hello到用戶端,因此 在TServerMethodClass類別之前和之後使用新的編譯器指令{$MethodInfo ON}和{$MethodInfo OFF}包圍,如此一來Tiburon的編譯器在編譯這個類別時便會產生額外的RTTI資訊。
6.    在TDSServerClass元件的OnGetClass事件處理函式中撰寫如下的程式碼:
procedure TForm6.DSServerClass1GetClass(DSServerClass: TDSServerClass;
  var PersistentClass: TPersistentClass);
begin
  PersistentClass := TServerMethodClass;
end;
TDSServerClass 元件的OnGetClass事件是用戶端向DataSnap JSON伺服器查詢可呼叫的服務類別時被呼叫,由於在這個範例中我們是要輸出TServerMethodClass類別之中的Hello函式,因此在 OnGetClass事件處理函式中把參數PersistentClass設定為TServerMethodClass類別。
現在這個分散式JSON伺服器已經完成,編譯它並且執行它,現在我們就擁有了一個不再需要使用COM/COM+的分散式伺服器了,它簡單,方便又快速,接下來我們就可以建立用戶端應用程式來呼叫它提供的服務方法了。

步驟 2 – 建立分散式用戶端

要建立分散式用戶端也非常的簡單,它的步驟如下:
1.    建立一個VCL Form的應用程式
2.    在主表單中加入TSQLConnection元件,在它的Driver特性中選擇使用DataSnap,並且在HostName中輸入分散式JSON伺服 器的名稱,由於我們是在相同的機器中執行,因此可以輸入localhost。另外注意它的Port特性值也是內定為211,各位可以參考下面的圖形:
 http://blufiles.storage.live.com/y1pWdXe2qE3z_mGnOcgJ2IjCf9l080ahaavIp0BBhqwYglaXORAuKicw0r6b9H2t-va
3.    在主表單中加入TSqlServerMethod元件,連結它到步驟1的TSQLConnection元件,此時下拉它的 ServerMethodName特性便可以看到許多伺服器輸出的方法,其中有許多方法是和管理有關的,我們以後有機會再說明,在這些輸出的方法中我們可 以找到分散式JSON伺服器輸出的TServerMethodClass.Hello,如下圖所示,請選擇 TServerMethodClass.Hello。
 http://blufiles.storage.live.com/y1puH4RS5tGnQSW5SBLmHghjJNv0MnkhOVV1k-TSvS24sleodthVCVnrXWi0qBc967i
TSqlServerMethod元件可以讓開發人員在用戶端呼叫遠端分散式JSON伺服器輸出的服務方法。
4.    最後在主表單的Button控制項的OnClick事件處理函式中撰寫如下的程式碼:
01 procedure TForm7.Button1Click(Sender: TObject);
02 begin
03   Self.SqlServerMethod1.ParamByName('Name').Value := Edit1.Text;
04   Self.SqlServerMethod1.ExecuteMethod;
05   Edit2.Text := Self.SqlServerMethod1.ParamByName('ReturnParameter').AsString;
06 end;

請 注意在03行中我們設定TSqlServerMethod元件的Param特性中’Name’這個參數的數值,但是’Name’這個參數是從那裡來的? 請回頭看看前面TServerMethodClass.Hello函式的宣告原型,它接受一個參數,它的名稱就是’Name’,因此 TSqlServerMethod元件可以分析遠端JSON伺服器輸出的方法,每一個參數的名稱就成為TSqlServerMethod元件的Param 特性中的名稱,而當TSqlServerMethod元件呼叫ExecuteMethod方法真正的執行完畢遠端JSON伺服器輸出的方法後,如果遠端 JSON伺服器輸出的方法會回傳函式值,接著開發人員可以藉由'ReturnParameter'這個名稱的參數來取得執行的結果,如同上面05行所示。
現在我們執行用戶端,點選按鈕就可以看到遠端JSON伺服器輸出的方法果然正確回傳了執行結果。
http://blufiles.storage.live.com/y1p_7G_RsOS0YI7QanN8a79BufNsZ1WJc7aoGn5dkSqLWiQzHf7LelYVnCLNuVQa-PT

使用簡單的Delphi Reflect功能

Tiburon強化了RTTI並且提供了簡易的Reflect程式單元可以讓JSON伺服器輸出服務到用戶端,我們也可以利用這個功能來驗證一下。
首先我建立一個新的VCL應用程式,在專案中建立兩個額外的類別,一個類別使用新的編譯器指令{$MethodInfo ON}和{$MethodInfo OFF}包圍:
unit uServerMethod;

interface

uses Sysutils, classes;

type

{$MethodInfo ON}
  TServerMethodClass = class(TPersistent)
  public
    function SayHello(const Name: string): string;
    function GetReflectMessage : String;
    procedure ReflectMe;
  private
    FData : String;
  end;
{$MethodInfo OFF}
另外一個則否:
unit u沒有MethodInfo的程式單元;

interface

uses Sysutils, classes;

type

  TServerMethodWithoutMethodInfoClass = class(TPersistent)
  public
    function SayHello(const Name: string): string;
    function GetReflectMessage : String;
    procedure ReflectMe;
  private
    FData : String;
  end;
各位可以看到Tiburon支援了Unicode之後連程式單元的名稱都可以使用中文命名。

接著我在主表單中加入參考ObjAuto程式單元,並且使用下面的程式碼就可以取得類別方法的資訊:
procedure TForm7.btn有MethodInfo的按鈕Click(Sender: TObject);
var
  aClassObj : TServerMethodClass;
  mdArray : TMethodInfoArray;
  iCount: Integer;
begin
  aClassObj := TServerMethodClass.Create;
  try
    mdArray := ObjAuto.GetMethods(aClassObj.ClassType);
    for iCount := 0 to Length(mdArray) - 1  do
    begin
      ListBox1.Items.Add(mdArray[iCount].Name);
    end;
  finally
    aClassObj.Free;
  end;
end;

procedure TForm7.Button2Click(Sender: TObject);
var
  aClassObj : TServerMethodWithoutMethodInfoClass;
  mdArray : TMethodInfoArray;
  iCount: Integer;
begin
  aClassObj := TServerMethodWithoutMethodInfoClass.Create;
  try
    mdArray := ObjAuto.GetMethods(aClassObj.ClassType);
    for iCount := 0 to Length(mdArray) - 1  do
    begin
      ListBox1.Items.Add(mdArray[iCount].Name);
    end;
  finally
    aClassObj.Free;
  end;
end;
ObjAuto.GetMethods 可以取得類別方法的資訊,如果類別沒有使用新的編譯器指令{$MethodInfo ON}和{$MethodInfo OFF}包圍,那麼就無法產生足夠的RTTI資訊,因此用戶端將無法存取(看到)類別中的方法。現在執行這個範例VCL應用程式,我們可以看到左邊的 ListBox可以顯示TServerMethodClass類別中的方法,而右邊的ListBox則無法顯示 TServerMethodWithoutMethodInfoClass類別中的方法。
 http://blufiles.storage.live.com/y1plWbTAwZT0q09Z1Sd2GsyplrLGWzXWckO4YAWgp9yl6Padan6mm1Eps2DxQ2Tl-3y
下圖是我使用TCP Viewer觀查前面分散式JSON伺服器和分散式用戶端之間訊息的結果,我們可以看到它們之間的確是使用JSON格式在傳遞訊息。
 http://blufiles.storage.live.com/y1plS_t7_bGa85QlVu_VJtOqw8qpnAzIqrumwU83daZehY0KqChOnE7619OjxDI1g2J
Tiburon 的分散式JSON架構除了可以輸出伺服器的服務之外,也可以結合資料庫實現真正的Thin-Client,離線資料架構型態的應用系統,這些都基於 Delphi開發人員原本就熟悉的DataSnap架構,我很快的會寫一小篇文章展示它是多麼的容易而且又是使用我們熟悉的DataSnap元件。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章