function TDSHTTPWebDispatcher.DispatchRequest(Sender: TObject;
Request: TWebRequest; Response: TWebResponse): Boolean;
begin
try
if Owner is TWebModule then
DataSnapWebModule := TWebModule(Owner);
try
try
RequiresServer;
TDSHTTPServerWebBroker(Self.FHttpServer).DispatchDataSnap(Request, Response);
Result := True;
except
on E: Exception do
begin
{ Default to 500, like web services. }
Response.StatusCode := ;
Result := True;
end;
end;
except
{ Swallow any unexpected exception, it will bring down some web servers }
Result := False;
end;
finally
{ Reset current DataSnapWebModule }
DataSnapWebModule := nil;
end;
end;

第10行代码中,请求被分配到TDSHTTPServerWebBorker中处理了。

 procedure TDSHTTPServerWebBroker.DispatchDataSnap(ARequest: TWebRequest;
AResponse: TWebResponse);
var
LDispatch: TDSHTTPDispatch;
LContext: TDSHTTPContextWebBroker;
begin
LDispatch := TDSHTTPApplication.Instance.HTTPDispatch;
if LDispatch <> nil then
DoCommand(LDispatch.Context, LDispatch.Request, LDispatch.Response)
else
begin
LContext := TDSHTTPContextWebBroker.Create(ARequest, AResponse);
try
DoCommand(LContext, LContext.FRequest, LContext.FResponse);
finally
LContext.Free;
end;
end;
end;

上面的第14行代码最终会转到TDSRESTServer类处理。

procedure TDSRESTServer.DoCommand(AContext: TDSHTTPContext; ARequestInfo: TDSHTTPRequest;
                                  AResponseInfo: TDSHTTPResponse);

 procedure TDSRESTServer.DoCommand(AContext: TDSHTTPContext; ARequestInfo: TDSHTTPRequest;
AResponseInfo: TDSHTTPResponse);
var
Request: string;
NextRequest: string;
NextContext: string;
RestCtxt: string;
StartDispatch: Boolean;
begin // HTTPDispatch object if necessary
StartDispatch := not TDSHTTPApplication.Instance.Dispatching;
if StartDispatch then
TDSHTTPApplication.Instance.StartDispatch(AContext, ARequestInfo, AResponseInfo);
try
{$IFNDEF POSIX}
if CoInitFlags = - then
CoInitializeEx(nil, COINIT_MULTITHREADED)
else
CoInitializeEx(nil, CoInitFlags);
{$ENDIF}
try
// check for context, if not found send the appropriate error message
Request := ARequestInfo.URI;
if Consume(FDSContext, Request, NextRequest) then
begin
Request := NextRequest;
if Consume(FRESTContext, Request, NextRequest) then
begin
// datasnap/rest
DoDSRESTCommand(ARequestInfo, AResponseInfo, NextRequest);
end
else if ConsumeOtherContext(Request, NextContext, NextRequest) then
begin
DoDSOtherCommand(AContext, ARequestInfo, AResponseInfo, NextContext, NextRequest, FDSServerName <> EmptyStr);
end
else
begin
RestCtxt := Trim(FRESTContext);
if RestCtxt = EmptyStr then
RestCtxt := SProtocolRestEmpty; AResponseInfo.ResponseNo := ; {rest or other service not found in URI}
AResponseInfo.ContentText := Format(SProtocolNotSupported, [Request, RestCtxt]);
AResponseInfo.CloseConnection := true;
end;
end
else
begin
// This may dispatch .js files for example
DoCommandOtherContext(AContext, ARequestInfo, AResponseInfo, Request);
end;
if Assigned(Self.FTrace ) then
begin
FTrace(Self, AContext, ARequestInfo, AResponseInfo);
end;
finally ClearInvocationMetadata();
{$IFNDEF POSIX}
CoUnInitialize;
{$ENDIF}
end;
finally
if StartDispatch then
TDSHTTPApplication.Instance.EndDispatch;
end;
end;

上面阴影的代码,一步一步的推进,先判断URI中是否包括Datasnap,再往判断是否包括REST,然后再继续处理。

到目前,代码已经从TWebModule到TDSHTTPWebDispatcher再到TDSRESTServer类中了。

而Delphi中,我们可以创建三种类型的DataSanp Server程序:

一是DataSanp REST App

二是DataSnap App

三是DataSnap WebBroker App

目前来看, Rest App和WebBroder App是很相似的。而 DataSanp App有些不同:

一是没有WebModule。

二是用 TDSHTTPService 代替了 TDSHTTPWebDispatcher。

三是Form1中代码简化了很多了,虽然project中也出现了  IdHTTPWebBrokerBridge,但也是不同的。(可以和rest app的比较)

 program Project1;

 uses
Vcl.Forms,
Web.WebReq,
IdHTTPWebBrokerBridge,
Unit1 in 'Unit1.pas' {Form1},
ServerMethodsUnit1 in 'ServerMethodsUnit1.pas',
ServerContainerUnit1 in 'ServerContainerUnit1.pas' {ServerContainer1: TDataModule}; {$R *.res} begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TServerContainer1, ServerContainer1);
Application.Run;
end.

机制有何不同?

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

  1. 读DataSnap源代码(一)

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

  2. 读DataSnap源代码(六)

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

  3. 读DataSnap源代码(四)

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

  4. 读DataSnap源代码(三)

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

  5. 读DataSnap源代码(二)

    program Project1; {$APPTYPE GUI} {$R *.dres} uses Vcl.Forms, Web.WebReq, IdHTTPWebBrokerBridge, Form ...

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

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

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

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

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

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

  9. dotnet 读 WPF 源代码笔记 渲染收集是如何触发

    在 WPF 里面,渲染可以从架构上划分为两层.上层是 WPF 框架的 OnRender 之类的函数,作用是收集应用程序渲染的命令.上层将收集到的应用程序绘制渲染的命令传给下层,下层是 WPF 的 GF ...

随机推荐

  1. 并发的HTTP请求,apache是如何响应的,以及如何调用php文件的

    作者:酒窝链接:https://www.zhihu.com/question/23786410/answer/153455460来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  2. 在Microsoft Power BI中创建地图的10种方法

    今天,我们来简单聊一聊“地图”. 在我们日常生活中,地图地位已经提升的越来越高,出门聚餐.驾驶.坐车.旅行......应运而生的就是各种Map APP. 作为数据分析师,我们今天不讲生活地图,要跟大家 ...

  3. python学习笔记第一周

    目录: 一.基础概念 1.变量与常量介绍 2.引号的使用 3.条件判断 4.while与for循环 5.input输入 6.getpass模块 7.python编码 二.作业 1.个人登录系统 2.多 ...

  4. Django之模板层-自定义过滤器以及标签

    自定义标签与过滤器 在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag. 在app中创建templatetags模块(模块名只能是t ...

  5. maven初级

    ANT 和 分布式 ANT 是一种构建工具,就是eclips中项目,建立,删除..等等都是. 高负载访问一个服务器的时候,服务器会出现卡机或者访问速率降低的问题,这个时候就需要分布式的使用,将一个项目 ...

  6. EmBitz1.11中将左边的目录弄出来

    在view→manager   然后就会出来

  7. input标签(图像域和隐藏域)

    图像域(图像提交按钮): <input type="image" name="..." src="imageurl"  /> 隐 ...

  8. PTA——时间转换

    PTA 7-14 然后是几点 #include<stdio.h> int main() { int a,b,hour,min; scanf("%d%d",&a, ...

  9. EasyUI 文本框回车和普通回车

    easyui 回车 $('#Destination_Code').textbox('textbox').bind('keypress', function (e) { ) { } } 普通回车 < ...

  10. hdu4407 Sum 容斥原理

    XXX is puzzled with the question below: 1, 2, 3, ..., n (1<=n<=400000) are placed in a line. T ...