读DataSnap源代码(二)

program Project1;
{$APPTYPE GUI}

{$R *.dres}

uses
  Vcl.Forms,
  Web.WebReq,
  IdHTTPWebBrokerBridge,
  FormUnit1 in ‘FormUnit1.pas‘ {Form1},
  ServerMethodsUnit1 in ‘ServerMethodsUnit1.pas‘,
  WebModuleUnit1 in ‘WebModuleUnit1.pas‘ {WebModule1: TWebModule};

{$R *.res}

begin{ 返回是什么,见下面的【绿色代码】 }
  if WebRequestHandler <> nil then
    WebRequestHandler.WebModuleClass := WebModuleClass;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

IdHTTPWebBrokerBridge单元中:

 1 initialization{** 挂钩 **}
 2   WebReq.WebRequestHandlerProc := IdHTTPWebBrokerBridgeRequestHandler;
 3 {$IFDEF HAS_CLASSVARS}
 4   {$IFNDEF HAS_CLASSDESTRUCTOR}
 5 finalization
 6   FreeAndNil(TIdHTTPWebBrokerBridgeRequestHandler.FWebRequestHandler);
 7   {$ENDIF}
 8 {$ELSE}
 9 finalization
10   FreeAndNil(IndyWebRequestHandler);
11 {$ENDIF}

WebRequestHandler是Web.WebReq中的一个方法:

1 function WebRequestHandler: TWebRequestHandler;
2 begin
3   if Assigned(WebRequestHandlerProc) then
4     Result := WebRequestHandlerProc     /** 指向 IdHTTPWebBrokerBridgeRequestHandler 函数了 **/
5   else
6     Result := nil;
7 end;

IdHTTPWebBrokerBridgeRequestHandler的定义:

 1 function IdHTTPWebBrokerBridgeRequestHandler: TWebRequestHandler;
 2 begin
 3   {$IFDEF HAS_CLASSVARS}
 4   if not Assigned(TIdHTTPWebBrokerBridgeRequestHandler.FWebRequestHandler) then
 5     TIdHTTPWebBrokerBridgeRequestHandler.FWebRequestHandler := TIdHTTPWebBrokerBridgeRequestHandler.Create(nil);
 6   Result := TIdHTTPWebBrokerBridgeRequestHandler.FWebRequestHandler;
 7   {$ELSE}
 8   if not Assigned(IndyWebRequestHandler) then
 9     IndyWebRequestHandler := TIdHTTPWebBrokerBridgeRequestHandler.Create(nil);
10   Result := IndyWebRequestHandler;
11   {$ENDIF}
12 end;

还记得(一)中的那个静态成员吗? 在第4行初始化了。

继续(一)中 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;

TIdHTTPWebBrokerBridgeRequestHandler并没有 override 父类(TWebRequestHandler)的HandleRequest方法. 看TWebRequestHandler.HandleRequest代码

 1 function TWebRequestHandler.HandleRequest(Request: TWebRequest;
 2   Response: TWebResponse): Boolean;
 3 var
 4   I: Integer;
 5   LWebModule: TComponent;
 6   LWebAppServices: IWebAppServices;
 7   LGetWebAppServices: IGetWebAppServices;
 8   LComponent: TComponent;
 9 begin
10   Result := False;
11   LWebModule := ActivateWebModules;
12   if Assigned(LWebModule) then
13   try
14     try
15       if Supports(IInterface(LWebModule), IGetWebAppServices, LGetWebAppServices) then
16         LWebAppServices := LGetWebAppServices.GetWebAppServices;
17       if LWebAppServices = nil then
18         for I := 0 to LWebModule.ComponentCount - 1 do
19         begin
20           LComponent := LWebModule.Components[I];
21           if Supports(LComponent, IWebAppServices, LWebAppServices) then
22             if LWebAppServices.Active then
23               break
24             else
25               LWebAppServices := nil;
26         end;
27       if LWebAppServices = nil then
28         LWebAppServices := TDefaultWebAppServices.Create;
29       LWebAppServices.InitContext(LWebModule, Request, Response);
30       try
31         try
32           Result := LWebAppServices.HandleRequest;
33         except
34           ApplicationHandleException(LWebAppServices.ExceptionHandler);
35         end;
36       finally
37         LWebAppServices.FinishContext;
38       end;
39       if Result and not Response.Sent then
40         Response.SendResponse;
41     except
42       ApplicationHandleException(LWebAppServices.ExceptionHandler);
43     end;
44   finally
45     DeactivateWebModules(LWebModule);
46   end;
47 end;

在上面代码中,可以看到 WebModule 字眼了, :)

时间: 2024-10-12 23:42:27

读DataSnap源代码(二)的相关文章

读DataSnap源代码(一)

Delphi的DataSnap用了一段时间了,但一直感觉有些地方还不够了解,所以花时间阅读了源代码,特作此烂笔头. Datasnap是在之前的WebBorker基础上搭建的,DataSnap向导自动生成了基础的代码,所以就以基础代码为起点来看看DataSnap的内部机制. 首选创建一个 Stand-alone 的REST App,  向导至少会为我们生成一个Form1和一个WebModule1, FormUnit1单元如下: unit FormUnit1; interface uses Wina

读DataSnap源代码(五)

1 function TDSHTTPWebDispatcher.DispatchRequest(Sender: TObject; 2 Request: TWebRequest; Response: TWebResponse): Boolean; 3 begin 4 try 5 if Owner is TWebModule then 6 DataSnapWebModule := TWebModule(Owner); 7 try 8 try 9 RequiresServer; 10 TDSHTTPS

读DataSnap源代码(三)

1 function TWebRequestHandler.HandleRequest(Request: TWebRequest; 2 Response: TWebResponse): Boolean; 3 var 4 I: Integer; 5 LWebModule: TComponent; 6 LWebAppServices: IWebAppServices; 7 LGetWebAppServices: IGetWebAppServices; 8 LComponent: TComponent

读DataSnap源代码(四)

继续篇中的 1 function TCustomWebDispatcher.DispatchAction(Request: TWebRequest; 2 Response: TWebResponse): Boolean; 3 var 4 I: Integer; 5 Action, Default: TWebActionItem; 6 Dispatch: IWebDispatch; 7 begin 8 FRequest := Request; 9 FResponse := Response; 10

蓝鸥Unity开发基础—— 实践课程源代码二

蓝鸥Unity开发基础-- 实践课程源代码二 using System; namespace MyFirstGame{    class MainClass    {        public static void Main (string[] args)        {            //游戏即将启动时做一些操作            const int mapW=46;//地图宽度            const int mapH = 16;//地图高度 //定义常量    

DataSnap初步二

转:https://blog.csdn.net/a00553344/article/details/51670486 1. 一个典型的DataSnap服务器至少需要三个控件: TDSServer: DataSnap的逻辑核心控件,控制服务器的运行. TDSServerClass: DataSnap服务端服务导出控件,通过OnGetClass事件来导出服务端的类及方法供客户端的远程调用. 作为服务端导出给客户端远程调用的类需要满足以下两个条件: 从TComponent类派生. 需要有{$METHO

Java并发程序设计(15)并发锁之读写锁(续二)写锁降级

1.1.1. 读写锁应用之三写锁降级 ReentrantReadWriteLock还具有写锁降级的特点,而这跟可重入性有一些关系. (1)持有写锁时可以降级为读锁. (2)持有读锁时不能升级为写锁. ReentrantReadWriteLock和ReentrantLock相似的是都有一个特点,就是可重入.可重入指已经获取到锁的线程可以再次获取锁,保证lock和unlock的次数相同即可. package com.test.concurrence; import java.util.Random;

扫雷 思路 与源代码 二

扫雷步骤2: 首先第一步:随机埋雷, 定义一个随机埋雷的对象,循环,取得一个整数范围的数量(0- 格子的数)如果这个格子有地雷为真,那么循环+1第二步:计算每个格子周边的格子的数量 用循环所有格子,其次在用一个cell类型的数组,并在周围格子的占内存中查找来存放当前方格周边所有的方格 并用int unm来记录 (传一个对象给我,然后统计当前的地雷)如果在周围格子中发现了地雷,记录下来并将值传给cell数组第三步:定义一个周边格子的的数组类将当前格子传给它. 先计算左右.上下.四个角,并返回一个值

读jQuery之二十(Deferred对象)

Deferred对象是由$.Deferred构造的,$.Deferred被实现为简单工厂模式. 它用来解决JS中的异步编程,它遵循 Common Promise/A 规范.实现此规范的还有 when.js 和 dojo. $.Deferred作为新特性首次出现在版本1.5中,这个版本利用Deferred又完全重写了Ajax模块. $.Deferred在jQuery代码自身四处被使用,分别是promise方法.DOM ready.Ajax模块.动画模块. 这里以版本1.8.3分析,由于1.7后$.