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 TDSHTTPServerWebBroker(Self.FHttpServer).DispatchDataSnap(Request, Response); 11 Result := True; 12 except 13 on E: Exception do 14 begin 15 { Default to 500, like web services. } 16 Response.StatusCode := 500; 17 Result := True; 18 end; 19 end; 20 except 21 { Swallow any unexpected exception, it will bring down some web servers } 22 Result := False; 23 end; 24 finally 25 { Reset current DataSnapWebModule } 26 DataSnapWebModule := nil; 27 end; 28 end;
第10行代码中,请求被分配到TDSHTTPServerWebBorker中处理了。
1 procedure TDSHTTPServerWebBroker.DispatchDataSnap(ARequest: TWebRequest; 2 AResponse: TWebResponse); 3 var 4 LDispatch: TDSHTTPDispatch; 5 LContext: TDSHTTPContextWebBroker; 6 begin 7 LDispatch := TDSHTTPApplication.Instance.HTTPDispatch; 8 if LDispatch <> nil then 9 DoCommand(LDispatch.Context, LDispatch.Request, LDispatch.Response) 10 else 11 begin 12 LContext := TDSHTTPContextWebBroker.Create(ARequest, AResponse); 13 try 14 DoCommand(LContext, LContext.FRequest, LContext.FResponse); 15 finally 16 LContext.Free; 17 end; 18 end; 19 end;
上面的第14行代码最终会转到TDSRESTServer类处理。
procedure TDSRESTServer.DoCommand(AContext: TDSHTTPContext; ARequestInfo: TDSHTTPRequest;
AResponseInfo: TDSHTTPResponse);
1 procedure TDSRESTServer.DoCommand(AContext: TDSHTTPContext; ARequestInfo: TDSHTTPRequest; 2 AResponseInfo: TDSHTTPResponse); 3 var 4 Request: string; 5 NextRequest: string; 6 NextContext: string; 7 RestCtxt: string; 8 StartDispatch: Boolean; 9 begin 10 11 // HTTPDispatch object if necessary 12 StartDispatch := not TDSHTTPApplication.Instance.Dispatching; 13 if StartDispatch then 14 TDSHTTPApplication.Instance.StartDispatch(AContext, ARequestInfo, AResponseInfo); 15 try 16 {$IFNDEF POSIX} 17 if CoInitFlags = -1 then 18 CoInitializeEx(nil, COINIT_MULTITHREADED) 19 else 20 CoInitializeEx(nil, CoInitFlags); 21 {$ENDIF} 22 try 23 // check for context, if not found send the appropriate error message 24 Request := ARequestInfo.URI; 25 if Consume(FDSContext, Request, NextRequest) then 26 begin 27 Request := NextRequest; 28 if Consume(FRESTContext, Request, NextRequest) then 29 begin 30 // datasnap/rest 31 DoDSRESTCommand(ARequestInfo, AResponseInfo, NextRequest); 32 end 33 else if ConsumeOtherContext(Request, NextContext, NextRequest) then 34 begin 35 DoDSOtherCommand(AContext, ARequestInfo, AResponseInfo, NextContext, NextRequest, FDSServerName <> EmptyStr); 36 end 37 else 38 begin 39 RestCtxt := Trim(FRESTContext); 40 if RestCtxt = EmptyStr then 41 RestCtxt := SProtocolRestEmpty; 42 43 AResponseInfo.ResponseNo := 501; {rest or other service not found in URI} 44 AResponseInfo.ContentText := Format(SProtocolNotSupported, [Request, RestCtxt]); 45 AResponseInfo.CloseConnection := true; 46 end; 47 end 48 else 49 begin 50 // This may dispatch .js files for example 51 DoCommandOtherContext(AContext, ARequestInfo, AResponseInfo, Request); 52 end; 53 if Assigned(Self.FTrace ) then 54 begin 55 FTrace(Self, AContext, ARequestInfo, AResponseInfo); 56 end; 57 finally 58 59 ClearInvocationMetadata(); 60 {$IFNDEF POSIX} 61 CoUnInitialize; 62 {$ENDIF} 63 end; 64 finally 65 if StartDispatch then 66 TDSHTTPApplication.Instance.EndDispatch; 67 end; 68 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的比较)
1 program Project1; 2 3 uses 4 Vcl.Forms, 5 Web.WebReq, 6 IdHTTPWebBrokerBridge, 7 Unit1 in 'Unit1.pas' {Form1}, 8 ServerMethodsUnit1 in 'ServerMethodsUnit1.pas', 9 ServerContainerUnit1 in 'ServerContainerUnit1.pas' {ServerContainer1: TDataModule}; 10 11 {$R *.res} 12 13 begin 14 Application.Initialize; 15 Application.MainFormOnTaskbar := True; 16 Application.CreateForm(TForm1, Form1); 17 Application.CreateForm(TServerContainer1, ServerContainer1); 18 Application.Run; 19 end.
机制有何不同?