读DataSnap源代码(五)
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源代码(五)的更多相关文章
- 读DataSnap源代码(一)
Delphi的DataSnap用了一段时间了,但一直感觉有些地方还不够了解,所以花时间阅读了源代码,特作此烂笔头. Datasnap是在之前的WebBorker基础上搭建的,DataSnap向导自动生 ...
- 读DataSnap源代码(六)
具体分析一下DataSanp App与Rest, WebBroker App的不同,先看TDSHTTPService. **************************************** ...
- 读DataSnap源代码(四)
继续篇中的 function TCustomWebDispatcher.DispatchAction(Request: TWebRequest; Response: TWebResponse): Bo ...
- 读DataSnap源代码(三)
function TWebRequestHandler.HandleRequest(Request: TWebRequest; Response: TWebResponse): Boolean; va ...
- 读DataSnap源代码(二)
program Project1; {$APPTYPE GUI} {$R *.dres} uses Vcl.Forms, Web.WebReq, IdHTTPWebBrokerBridge, Form ...
- 读Flask源代码学习Python--config原理
读Flask源代码学习Python--config原理 个人学习笔记,水平有限.如果理解错误的地方,请大家指出来,谢谢!第一次写文章,发现好累--!. 起因 莫名其妙在第一份工作中使用了从来没有接 ...
- session自己定义存储,怎样更好地进行session共享;读tomcat7源代码,org.apache.catalina.session.FileStore可知
session自己定义存储.怎样更好地进行session共享: 读tomcat源代码,org.apache.catalina.session.FileStore可知 一.详见: 方法1 public ...
- dotnet 读 WPF 源代码笔记 布局时 Arrange 如何影响元素渲染坐标
大家是否好奇,在 WPF 里面,对 UIElement 重写 OnRender 方法进行渲染的内容,是如何受到上层容器控件的布局而进行坐标偏移.如有两个放入到 StackPanel 的自定义 UIEl ...
- dotnet 读 WPF 源代码笔记 渲染收集是如何触发
在 WPF 里面,渲染可以从架构上划分为两层.上层是 WPF 框架的 OnRender 之类的函数,作用是收集应用程序渲染的命令.上层将收集到的应用程序绘制渲染的命令传给下层,下层是 WPF 的 GF ...
随机推荐
- 使用std::map和std::list存放数据,消耗内存比实际数据大得多
使用std::map和std::list存放数据,消耗内存比实际数据大得多 场景:项目中需要存储一个结构,如下程序段中TEST_DATA_STRU,结构占24B.但是使用代码中的std::list&l ...
- 在 子 iframe中 点击一个按钮, 变换 这个 iframe的地址url.
//跳到测试结果: function jump() { console.log(self.parent.document.getElementById("iframe").src) ...
- 2016 多校联赛7 Balls and Boxes(概率期望)
Mr. Chopsticks is interested in random phenomena, and he conducts an experiment to study randomness. ...
- 效率生产力工具 —— idea 插件
maven helper: 打开该pom文件的Dependency Analyzer视图(在文件打开之后,文件下面会多出这样一个tab), 进入Dependency Analyzer视图之后有三个查看 ...
- Python学习笔记第四周
目录 一.基础概念 1.装饰器 1.装饰器本质就是函数 2.实现装饰器知识储备 1.函数即变量 2.高阶函数 3.嵌套函数 例子 1.将一个函数名作为实参传递给另外一个函数 2.返回值为函数名 3.函 ...
- BT觀念分享和常見問題彙整
一. TCP/IP基本觀念 1. IP : 每台在TCP/IP網路上的電腦必須具備的一個代表號或一個地址.IP又分為private IP(192.168.x.x /10.x.x.x /172.16.x ...
- Java调用Lua脚本(热载实现)
前言: Lua作为解析执行的脚本语言, 往往是易变逻辑编写的首选语言, 尤其是在游戏领域. C/C++和Lua的结合, 往往了标配. 比如Redis, Nginx其对Lua的支持, 也是杠杠的. 当然 ...
- linux 禁ping和开启ping方法
Linux 禁ping和开启ping操作# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all如果要恢复,只要:# echo 0 > /pro ...
- SQLI DUMB SERIES-5
less5 (1)输入单引号,回显错误,说明存在注入点.输入的Id被一对单引号所包围,可以闭合单引号 (2)输入正常时:?id=1 说明没有显示位,因此不能使用联合查询了:可以使用报错注入,有两种方式 ...
- ROI-Align解决方案
https://yq.aliyun.com/articles/558181 Mask R-CNN与Faster R-CNN相似,Faster R-CNN是two-stage的,其中第一个stage是R ...