zoukankan      html  css  js  c++  java
  • 读DataSnap源代码(一)

    Delphi的DataSnap用了一段时间了,但一直感觉有些地方还不够了解,所以花时间阅读了源代码,特作此烂笔头。

    Datasnap是在之前的WebBorker基础上搭建的,DataSnap向导自动生成了基础的代码,所以就以基础代码为起点来看看DataSnap的内部机制。

    首选创建一个 Stand-alone 的REST App,  向导至少会为我们生成一个Form1和一个WebModule1,

    FormUnit1单元如下:

    unit FormUnit1;
    
    interface
    
    uses
      Winapi.Messages, System.SysUtils, System.Variants,
      System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
      Vcl.AppEvnts, Vcl.StdCtrls, IdHTTPWebBrokerBridge, Web.HTTPApp;
    
    type
      TForm1 = class(TForm)
        ButtonStart: TButton;
        ButtonStop: TButton;
        EditPort: TEdit;
        Label1: TLabel;
        ApplicationEvents1: TApplicationEvents;
        ButtonOpenBrowser: TButton;
        procedure FormCreate(Sender: TObject);
        procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
        procedure ButtonStartClick(Sender: TObject);
        procedure ButtonStopClick(Sender: TObject);
        procedure ButtonOpenBrowserClick(Sender: TObject);
      private
        FServer: TIdHTTPWebBrokerBridge;
        procedure StartServer;
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    uses
      WinApi.Windows, Winapi.ShellApi, Datasnap.DSSession;
    
    procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
    begin
      ButtonStart.Enabled := not FServer.Active;
      ButtonStop.Enabled := FServer.Active;
      EditPort.Enabled := not FServer.Active;
    end;
    
    procedure TForm1.ButtonOpenBrowserClick(Sender: TObject);
    var
      LURL: string;
    begin
      StartServer;
      LURL := Format('http://localhost:%s', [EditPort.Text]);
      ShellExecute(0,
            nil,
            PChar(LURL), nil, nil, SW_SHOWNOACTIVATE);
    end;
    
    procedure TForm1.ButtonStartClick(Sender: TObject);
    begin
      StartServer;
    end;
    
    procedure TerminateThreads;
    begin
      if TDSSessionManager.Instance <> nil then
        TDSSessionManager.Instance.TerminateAllSessions;
    end;
    
    procedure TForm1.ButtonStopClick(Sender: TObject);
    begin
      TerminateThreads;
      FServer.Active := False;
      FServer.Bindings.Clear;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      FServer := TIdHTTPWebBrokerBridge.Create(Self);
    end;
    
    procedure TForm1.StartServer;
    begin
      if not FServer.Active then
      begin
        FServer.Bindings.Clear;
        FServer.DefaultPort := StrToInt(EditPort.Text);
        FServer.Active := True;
      end;
    end;
    
    end.
    

     在Form1中,有一个FServer ,ButtonStart.Click事件中有FServer.Active := True;

    TIdHTTPWebBrokerBridge 是  TIdHTTPWebBrokerBridge = class(TIdCustomHTTPServer)

    到目前上为,至少知道Datasanp是基于Id组件的,那么Id(idHttpServer)和WebModule, DSServer, DSHTTPWebDispatcher1 是如何关连上的,又是如何调用到

    DDServerClass实例方法呢?

     1   TIdHTTPWebBrokerBridge = class(TIdCustomHTTPServer)
     2   private
     3     procedure RunWebModuleClass(AThread: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
     4      AResponseInfo: TIdHTTPResponseInfo);
     5   protected
     6     FWebModuleClass: TComponentClass;
     7     //
     8     procedure DoCommandGet(AThread: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
     9      AResponseInfo: TIdHTTPResponseInfo); override;
    10     procedure DoCommandOther(AThread: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
    11      AResponseInfo: TIdHTTPResponseInfo); override;
    12     procedure InitComponent; override;
    13   public
    14     procedure RegisterWebModuleClass(AClass: TComponentClass);
    15   end;

    DoCommandGet的内部代码:

    procedure TIdHTTPWebBrokerBridge.DoCommandGet(AThread: TIdContext;
     ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
    begin
      if FWebModuleClass <> nil then begin
        // FWebModuleClass, RegisterWebModuleClass supported for backward compatability
        RunWebModuleClass(AThread, ARequestInfo, AResponseInfo)
      end else
      begin
        {$IFDEF HAS_CLASSVARS}
        TIdHTTPWebBrokerBridgeRequestHandler.FWebRequestHandler.Run(AThread, ARequestInfo, AResponseInfo);
        {$ELSE}
        IndyWebRequestHandler.Run(AThread, ARequestInfo, AResponseInfo);
        {$ENDIF}
      end;
    end;

    TIdHTTPWebBrokerBridgeRequestHandler的定义:

     1   TIdHTTPWebBrokerBridgeRequestHandler = class(TWebRequestHandler)
     2   {$IFDEF HAS_CLASSVARS}
     3   private
     4    class var FWebRequestHandler: TIdHTTPWebBrokerBridgeRequestHandler;
     5   {$ENDIF}
     6   public
     7     constructor Create(AOwner: TComponent); override;
     8     {$IFDEF HAS_CLASSVARS}
     9       {$IFDEF HAS_CLASSDESTRUCTOR}
    10     class destructor Destroy;
    11       {$ENDIF}
    12     {$ENDIF}
    13     destructor Destroy; override;
    14     procedure Run(AThread: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
    15   end;


    第4行,静态的,唯一的。

    第14行 就是TIdHTTPWebBrokerBridge.DoCommandGet中被调用的。

    Run内部代码:

     1 procedure TIdHTTPWebBrokerBridgeRequestHandler.Run(AThread: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
     2 var
     3   LRequest: TIdHTTPAppRequest;
     4   LResponse: TIdHTTPAppResponse;
     5 begin
     6   try
     7     LRequest := TIdHTTPAppRequest.Create(AThread, ARequestInfo, AResponseInfo);
     8     try
     9       LResponse := TIdHTTPAppResponse.Create(LRequest, AThread, ARequestInfo, AResponseInfo);
    10       try
    11         // WebBroker will free it and we cannot change this behaviour
    12         AResponseInfo.FreeContentStream := False;
    13         HandleRequest(LRequest, LResponse);
    14       finally
    15         FreeAndNil(LResponse);
    16       end;
    17     finally
    18       FreeAndNil(LRequest);
    19     end;
    20   except
    21     // Let Indy handle this exception
    22     raise;
    23   end;
    24 end;


     

  • 相关阅读:
    笔记-归并排序
    Repeated Substring Pattern
    Assign Cookies
    Number of Boomerangs
    Paint Fence
    Path Sum III
    Valid Word Square
    Sum of Two Integers
    Find All Numbers Disappeared in an Array
    First Unique Character in a String
  • 原文地址:https://www.cnblogs.com/Jiaojiawang/p/4818454.html
Copyright © 2011-2022 走看看