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单元中:

 initialization
{** 挂钩 **}

2 WebReq.WebRequestHandlerProc := IdHTTPWebBrokerBridgeRequestHandler;
{$IFDEF HAS_CLASSVARS}
{$IFNDEF HAS_CLASSDESTRUCTOR}
finalization
FreeAndNil(TIdHTTPWebBrokerBridgeRequestHandler.FWebRequestHandler);
{$ENDIF}
{$ELSE}
finalization
FreeAndNil(IndyWebRequestHandler);
{$ENDIF}

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

 function WebRequestHandler: TWebRequestHandler;
begin
if Assigned(WebRequestHandlerProc) then
Result := WebRequestHandlerProc /** 指向 IdHTTPWebBrokerBridgeRequestHandler 函数了 **/
else
Result := nil;
end;

IdHTTPWebBrokerBridgeRequestHandler的定义:

 function IdHTTPWebBrokerBridgeRequestHandler: TWebRequestHandler;
begin
{$IFDEF HAS_CLASSVARS}
if not Assigned(TIdHTTPWebBrokerBridgeRequestHandler.FWebRequestHandler) then
TIdHTTPWebBrokerBridgeRequestHandler.FWebRequestHandler := TIdHTTPWebBrokerBridgeRequestHandler.Create(nil);
Result := TIdHTTPWebBrokerBridgeRequestHandler.FWebRequestHandler;
{$ELSE}
if not Assigned(IndyWebRequestHandler) then
IndyWebRequestHandler := TIdHTTPWebBrokerBridgeRequestHandler.Create(nil);
Result := IndyWebRequestHandler;
{$ENDIF}
end;

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

继续(一)中 Run 函数中的代码:

 procedure TIdHTTPWebBrokerBridgeRequestHandler.Run(AThread: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
LRequest: TIdHTTPAppRequest;
LResponse: TIdHTTPAppResponse;
begin
try
LRequest := TIdHTTPAppRequest.Create(AThread, ARequestInfo, AResponseInfo);
try
LResponse := TIdHTTPAppResponse.Create(LRequest, AThread, ARequestInfo, AResponseInfo);
try
// WebBroker will free it and we cannot change this behaviour
AResponseInfo.FreeContentStream := False;
HandleRequest(LRequest, LResponse);
finally
FreeAndNil(LResponse);
end;
finally
FreeAndNil(LRequest);
end;
except
// Let Indy handle this exception
raise;
end;
end;

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

 function TWebRequestHandler.HandleRequest(Request: TWebRequest;
Response: TWebResponse): Boolean;
var
I: Integer;
LWebModule: TComponent;
LWebAppServices: IWebAppServices;
LGetWebAppServices: IGetWebAppServices;
LComponent: TComponent;
begin
Result := False;
LWebModule := ActivateWebModules;
if Assigned(LWebModule) then
try
try
if Supports(IInterface(LWebModule), IGetWebAppServices, LGetWebAppServices) then
LWebAppServices := LGetWebAppServices.GetWebAppServices;
if LWebAppServices = nil then
for I := to LWebModule.ComponentCount - do
begin
LComponent := LWebModule.Components[I];
if Supports(LComponent, IWebAppServices, LWebAppServices) then
if LWebAppServices.Active then
break
else
LWebAppServices := nil;
end;
if LWebAppServices = nil then
LWebAppServices := TDefaultWebAppServices.Create;
LWebAppServices.InitContext(LWebModule, Request, Response);
try
try
Result := LWebAppServices.HandleRequest;
except
ApplicationHandleException(LWebAppServices.ExceptionHandler);
end;
finally
LWebAppServices.FinishContext;
end;
if Result and not Response.Sent then
Response.SendResponse;
except
ApplicationHandleException(LWebAppServices.ExceptionHandler);
end;
finally
DeactivateWebModules(LWebModule);
end;
end;

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

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

  1. 读DataSnap源代码(五)

    function TDSHTTPWebDispatcher.DispatchRequest(Sender: TObject; Request: TWebRequest; Response: TWebR ...

  2. 读DataSnap源代码(一)

    Delphi的DataSnap用了一段时间了,但一直感觉有些地方还不够了解,所以花时间阅读了源代码,特作此烂笔头. Datasnap是在之前的WebBorker基础上搭建的,DataSnap向导自动生 ...

  3. 读DataSnap源代码(六)

    具体分析一下DataSanp App与Rest, WebBroker App的不同,先看TDSHTTPService. **************************************** ...

  4. 读DataSnap源代码(四)

    继续篇中的 function TCustomWebDispatcher.DispatchAction(Request: TWebRequest; Response: TWebResponse): Bo ...

  5. 读DataSnap源代码(三)

    function TWebRequestHandler.HandleRequest(Request: TWebRequest; Response: TWebResponse): Boolean; va ...

  6. session自己定义存储,怎样更好地进行session共享;读tomcat7源代码,org.apache.catalina.session.FileStore可知

    session自己定义存储.怎样更好地进行session共享: 读tomcat源代码,org.apache.catalina.session.FileStore可知 一.详见: 方法1 public ...

  7. 读Flask源代码学习Python--config原理

    读Flask源代码学习Python--config原理 个人学习笔记,水平有限.如果理解错误的地方,请大家指出来,谢谢!第一次写文章,发现好累--!. 起因   莫名其妙在第一份工作中使用了从来没有接 ...

  8. dotnet 读 WPF 源代码笔记 布局时 Arrange 如何影响元素渲染坐标

    大家是否好奇,在 WPF 里面,对 UIElement 重写 OnRender 方法进行渲染的内容,是如何受到上层容器控件的布局而进行坐标偏移.如有两个放入到 StackPanel 的自定义 UIEl ...

  9. DataSnap初步二

    转:https://blog.csdn.net/a00553344/article/details/51670486 1. 一个典型的DataSnap服务器至少需要三个控件: TDSServer: D ...

随机推荐

  1. linux之ls、ll

    ls == list,根据不同的选项,列举指定目录或文件的相关信息,是Unix/Linux下最常用的命令之一,cd到某一目录下后执行的第一个命令. ls命令格式:ls [OPTION]... [FIL ...

  2. 用户访一个APP或者网页流程示意图

    用户访问示意图:

  3. select标签的相关操作,选中,获取option的值,二级联动

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  4. LeetCode--122、167、169、189、217 Array(Easy)

    122. Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price ...

  5. Golang AES加密

    package main import ( "crypto/aes" "crypto/cipher" "fmt" "os" ...

  6. 2017-2018-2 20165228 实验四《Android程序设计》实验报告

    一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:苏祚堃 学号:20165228 指导教师:娄嘉鹏 实验日期:2018年5月14日 实验时间:13:45 - 3:25 实验序号:实验四 ...

  7. DG搭建方式区分

    DG搭建三种方式: 一.异机恢复,restore database,recover database 二. duplicate target database for standby from act ...

  8. 洛谷 P1164:小A点菜(DP/DFS)

    题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家--餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:"随便点". 题目描述 不过ui ...

  9. PTA——各位数之和

    PTA 7-28 求整数的位数及各位数字之和 我的程序: #include<stdio.h> #include<math.h> int main(){ ,t; scanf(&q ...

  10. RPC 原理

    转载地址:你应该知道的 RPC 原理 在校期间大家都写过不少程序,比如写个hello world服务类,然后本地调用下,如下所示.这些程序的特点是服务消费方和服务提供方是本地调用关系. 而一旦踏入公司 ...