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?