Recent

Author Topic: [Solved] Create a web server in a different Unit  (Read 633 times)

SKBotNL

  • New member
  • *
  • Posts: 9
[Solved] Create a web server in a different Unit
« on: May 14, 2023, 12:00:05 pm »
Hello,
I have a Forms application and I want to add a webserver to it, but when I want to for example set a port I need to use Application.Port, which doesnt exist when I'm creating a forms application. When adding "fphttpapp" to the uses other properties break. What can I do?
« Last Edit: May 14, 2023, 01:44:59 pm by SKBotNL »

SKBotNL

  • New member
  • *
  • Posts: 9
Re: Create a web server in a different Unit
« Reply #1 on: May 14, 2023, 01:44:31 pm »
Yet another one I finally fixed myself.
Code: Pascal  [Select][+][-]
  1. program simplehttpserver;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$define UseCThreads}
  5.  
  6. uses
  7.   cthreads, sysutils, Classes, fphttpserver;
  8.  
  9. Type
  10.  
  11.   { TTestHTTPServer }
  12.  
  13.   TTestHTTPServer = Class(TFPHTTPServer)
  14.   public
  15.     procedure HandleRequest(Var ARequest: TFPHTTPConnectionRequest;
  16.                             Var AResponse : TFPHTTPConnectionResponse); override;
  17.  
  18.   end;
  19.  
  20. Var
  21.   Serv : TTestHTTPServer;
  22. { TTestHTTPServer }
  23.  
  24. procedure TTestHTTPServer.HandleRequest(var ARequest: TFPHTTPConnectionRequest;
  25.   var AResponse: TFPHTTPConnectionResponse);
  26. begin
  27.   AResponse.Content := 'hi';
  28.   AResponse.SendContent;
  29. end;
  30.  
  31. begin
  32.   Serv:=TTestHTTPServer.Create(Nil);
  33.   try
  34.     Serv.Threaded:=False;
  35.     Serv.Port:=8080;
  36.     Serv.AcceptIdleTimeout:=1000;
  37.     Serv.Active:=True;
  38.   finally
  39.     Serv.Free;
  40.   end;
  41. end.
This doesn't use "Applications" so it's way easier to implement in a Unit.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: [Solved] Create a web server in a different Unit
« Reply #2 on: May 17, 2023, 08:19:09 am »
There's Application object in these units:
  • Forms
  • FPHTTPApp
  • FPHTTPSys
  • FPFCGI
  • FPCGI
So if you want to access each, you must qualify with the unit name such as: Forms.Application, fphttpapp.Application and so on.
The problem is that each Application is also designed as an event loop consumer than runs synchronously on the call of its .Run method.
Therefore, you will also need to make both the call asynchronous as well as providing a replacement "wait" mechanism that waits for all .Run methods to finish, like so (WARNING: untested code):
Code: Pascal  [Select][+][-]
  1. function RunFormsLoop(parameter: pointer): PtrInt;
  2. begin
  3.   Forms.Application.Run;
  4. end;
  5.  
  6. function RunFPHTTPAppLoop(parameter: pointer): PtrInt;
  7. begin
  8.   FPHTTPApp.Application.Run;
  9. end;
  10.  
  11. function FormsLoopTerminated: Boolean;
  12. begin
  13.   Result := Forms.Application.Terminated;
  14. end;
  15.  
  16. function FPHTTPAppLoopTerminated: Boolean;
  17. begin
  18.   Result := FPHTTPApp.Application.Terminated;
  19. end;
  20.  
  21. ...
  22.  
  23. begin
  24.   BeginThread(@RunFormsLoop);
  25.   BeginThread(@RunFPHTTPAppLoop);
  26.   repeat until FormsLoopTerminated and FPHTTPAppLoopTerminated;
  27. end.
  28.  

 

TinyPortal © 2005-2018