Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TIdHTTPWebBrokerBridge im Thread = EResNotFound (https://www.delphipraxis.net/206331-tidhttpwebbrokerbridge-im-thread-%3D-eresnotfound.html)

Hobbycoder 10. Dez 2020 17:39

TIdHTTPWebBrokerBridge im Thread = EResNotFound
 
Ich versuche gerade meinen AppServer in einen Thread zu packen. Grund ist, dass ich später diesen als Service laufen lassen will, und dann kann ich den Thread einfach in den TService übernehmen und fertig.

Nun stoße ich auf ein Problem, für das ich keine Lösung finden. Liegt sicherlich daran, dass ich vieles von dem AppServer noch nicht ganz verstanden habe.

Ich erzeuge mir meinen Thread udn erstelle mir die TIdHTTPWebBrokerBridge
Delphi-Quellcode:
procedure TWebServerThread.Execute;
var
  LIOHandleSSL: TIdServerIOHandlerSSLOpenSSL;
begin
  self.FreeOnTerminate:=True;
  Self.NameThreadForDebugging('WebServerThread');
  FServer := TIdHTTPWebBrokerBridge.Create;
  if WebRequestHandler<>nil then
    WebRequestHandler.WebModuleClass := WebModuleClass;
  try
    FServer.RegisterWebModuleClass(WebModuleClass);
    if (FCertFile<>'') and FSSL then
    begin
      LIOHandleSSL := TIdServerIOHandlerSSLOpenSSL.Create(FServer);
      LIOHandleSSL.SSLOptions.CertFile := FCertFile; // ExtractFilePath(Application.ExeName)+'cert.pem';
      LIOHandleSSL.SSLOptions.RootCertFile := FRootFile; // ExtractFilePath(Application.ExeName)+'root.pem';
      LIOHandleSSL.SSLOptions.KeyFile := FKeyFile; // ExtractFilePath(Application.ExeName)+'key.pem';
      LIOHandleSSL.OnGetPassword := OnGetSSLPassword;
      LIOHandleSSL.SSLOptions.Method:=sslvTLSv1_2;
      LIOHandleSSL.SSLOptions.SSLVersions:=[sslvTLSv1_2];
      FServer.IOHandler := LIOHandleSSL;
    end;
    FServer.OnContextCreated:=OnContextCreated;
    FServer.Bindings.Clear;
    FServer.DefaultPort:=FPort;
    FServer.Active:=True;
    while not Self.Terminated do
      Sleep(20);
  finally
    FServer.Active:=False;
    FServer.Bindings.Clear;
    FreeAndNil(FServer);
  end;
end;
Und dazu erstmal ein leeres TWebModule:
Delphi-Quellcode:
unit uWebModule;

interface

uses System.Classes, Web.WebReq, Web.HTTPApp, Web.ReqMulti, IdHTTPWebBrokerBridge;

type
  TDBWebModule=class(TWebModule)
  private
    procedure DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
  public
    FSessionList: TSessionList;
    constructor Create(AOwner: TComponent); override;
  end;

var
  WebModuleClass: TComponentClass = TDBWebModule;

implementation

uses
  uWebServerThread;

{ TDBWebModule }

constructor TDBWebModule.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  with Actions.Add do
  begin
    Default:=True;
    Name:='DefaultHandler';
    PathInfo:='\';
    OnAction:=DefaultHandlerAction;
  end;
end;

procedure TDBWebModule.DefaultHandlerAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  Handled:=True;
  Response.Content:='<html><head></head><body><h2>Web-Server</h2></body></html>';
end;

end.
Beim Starten läuft das so erst mal und nimmt auch die Anfragen entgegen.
Jedoch beim TDBWebModule.Create in der Zeile inherited kommt es immer zu einer Exception 'EResNotFound' (Resource TDBWebModule nicht gefunden).
Wenn ich mich dann per Einzelschritt durchtaste, dann lande ich in der Web.HTTPApp und dort in der TWebModule.Create-Methode:
Delphi-Quellcode:
  if (ClassType <> TCustomWebDispatcher) and not (csDesigning in ComponentState) then
  try
    if not InitInheritedComponent(Self, TCustomWebDispatcher) then
      raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);
Mangels explizitem Detailwissen tippe ich mal ins Blaue. Entweder brauchts einen Owner für die TIdHTTPBrokerBridge, oder ich kann TWebModule gar nicht hier verwenden.
Wäre möglicherweise TCustomWebDispatcher der passenden Ersatz? Oder ist mein Vorgehen gänzlich falsch?

Olli73 10. Dez 2020 20:23

AW: TIdHTTPWebBrokerBridge im Thread = EResNotFound
 
Was genau hast du eigentlich vor? Warum kannst du nicht einfach eine Webbroker-Anwendung erstellen?

In dem Fall bräuchtest du dich eigentlich auch nicht um Threads zu kümmern, denn jede Serveranfrage bekommt eine eigene Instanz vom WebModule und läuft automatisch im Thread.

Hobbycoder 10. Dez 2020 21:04

AW: TIdHTTPWebBrokerBridge im Thread = EResNotFound
 
Zitat:

Zitat von Olli73 (Beitrag 1478899)
Was genau hast du eigentlich vor? Warum kannst du nicht einfach eine Webbroker-Anwendung erstellen?

In dem Fall bräuchtest du dich eigentlich auch nicht um Threads zu kümmern, denn jede Serveranfrage bekommt eine eigene Instanz vom WebModule und läuft automatisch im Thread.

Ist mir bekannt. Das war auch nicht meine Frage. Trotzdem danke für den Hinweis.

Hobbycoder 11. Dez 2020 10:40

AW: TIdHTTPWebBrokerBridge im Thread = EResNotFound
 
Zitat:

Zitat von Olli73 (Beitrag 1478899)
Was genau hast du eigentlich vor? Warum kannst du nicht einfach eine Webbroker-Anwendung erstellen?

Wie oben geschrieben möchte ich das ganze später in einen Service packen. Zum Debuggen finde ich es aber einfacher, parallel zum Service eine Desktopanwendung zu haben, in der ich bequem unterschiedliches Verhalten und Date leicht analysieren kann. Ist der Thread erst einmal geschrieben, kann ich den sowohl im TService als auch in eine Application packen, kann über die Application alles Schick machen und habe damit den Service automatisch auch gut am laufen.

Aber vor allem möchte ich verstehen warum der Fehler auftritt.
Manchmal macht man auch Sachen, die vielleicht anders leichter wären, nur um sich zusammenhänge zu verdeutlichen.

Olli73 11. Dez 2020 10:54

AW: TIdHTTPWebBrokerBridge im Thread = EResNotFound
 
Zitat:

Zitat von Hobbycoder (Beitrag 1478928)
Wie oben geschrieben möchte ich das ganze später in einen Service packen. Zum Debuggen finde ich es aber einfacher, parallel zum Service eine Desktopanwendung zu haben, in der ich bequem unterschiedliches Verhalten und Date leicht analysieren kann. Ist der Thread erst einmal geschrieben, kann ich den sowohl im TService als auch in eine Application packen, kann über die Application alles Schick machen und habe damit den Service automatisch auch gut am laufen.

Also ich mache das so, dass ich zuerst eine Desktop-Anwendung erstelle und dann die Projektdatei so umbaue, dass es ein Service wird. Um beides (VCL-Anwendung und Service) parallel zu haben mache ich entweder 2 Projektdateien oder arbeite mit Compilerschaltern.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz