* * *

Author Topic: TFPHTTPServer in a thread  (Read 209 times)

jabounet

  • New member
  • *
  • Posts: 29
TFPHTTPServer in a thread
« on: March 12, 2017, 08:11:43 pm »



Hello all !


I'm trying to put a http server in my program to handle simple http requests.
To do that I used this example http://forum.lazarus.freepascal.org/index.php/topic,32353.msg208620.html#msg208620, using fhttpserver library.


Everything works fine, but I got an issue freeing the Server, and a memory leak is present.


Here is an example :


Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3.  
  4. {$mode objfpc}{$H+}
  5.  
  6.  
  7. interface
  8.  
  9.  
  10. uses
  11.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  12.   fphttpserver, fpHTTP, fpWeb;
  13.  
  14.  
  15. type
  16.  
  17.  
  18.   { TForm1 }
  19.  
  20.  
  21.   TForm1 = class(TForm)
  22.     Button1: TButton;
  23.     Button2: TButton;
  24.     procedure Button1Click(Sender: TObject);
  25.     procedure Button2Click(Sender: TObject);
  26.     procedure FormDestroy(Sender: TObject);
  27.   private
  28.     { private declarations }
  29.   public
  30.     { public declarations }
  31.      procedure DoHandleRequest(Sender:TObject; var ARequest:TFPHTTPConnectionRequest; var AResponse:TFPHTTPConnectionResponse);
  32.  
  33.  
  34.   end;
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.    { THTTPServerThread }
  42.  
  43.  
  44.    THTTPServerThread = class(TThread)
  45.    Private
  46.      Fserver : TFPHTTPServer;
  47.    Public
  48.      Constructor Create(APort:Word; const OnRequest:THTTPServerRequestHandler);
  49.      Procedure Execute; Override;
  50.      Procedure DoTerminate; Override;
  51.      Property Server : TFPHTTPServer Read FServer;
  52.    end;
  53.  
  54.  
  55.  var
  56.    Form1: TForm1;
  57.    FServerThread:TFPHTTPServer;
  58.  
  59.  
  60. implementation
  61.  
  62.  
  63. {$R *.lfm}
  64.  
  65.  
  66.  
  67.  
  68. procedure TForm1.DoHandleRequest(Sender: TObject;
  69.   var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse);
  70. begin
  71.  showmessage( ARequest.QueryString);
  72. end;
  73.  
  74.  
  75. procedure TForm1.Button1Click(Sender: TObject);
  76. begin
  77.      FServerthread := THTTPServerThread.Create(8080,@DoHandleRequest);
  78.      FServerthread.Start;
  79. end;
  80.  
  81.  
  82. procedure TForm1.Button2Click(Sender: TObject);
  83. begin
  84.   FServerThread.Terminate;
  85. end;
  86.  
  87.  
  88. procedure TForm1.FormDestroy(Sender: TObject);
  89. begin
  90.     if Assigned(Fserverthread) then
  91.   begin
  92.     Fserverthread.Terminate;
  93.     Fserverthread.WaitFor;
  94.     FreeAndNil(Fserverthread);
  95.   end;
  96. end;
  97.  
  98.  
  99. constructor THTTPServerThread.Create(APort: Word;
  100.   const OnRequest: THTTPServerRequestHandler);
  101. begin
  102.   Inherited Create(True);
  103.   FServer := TFPHTTPServer.Create(Nil);
  104.      FServer.Threaded:=true;
  105.      FServer.Port := APort;
  106.      FServer.OnRequest := OnRequest;
  107.  
  108.  
  109. end;
  110.  
  111.  
  112. procedure THTTPServerThread.Execute;
  113. begin
  114.         try
  115.            FServer.Active:=true;
  116.            while not terminated do sleep(10);
  117.         finally
  118.            FreeAndNil(FServer);
  119.         end;
  120. end;
  121.  
  122.  
  123. procedure THTTPServerThread.DoTerminate;
  124. begin
  125.   inherited DoTerminate;
  126.   FServer.Active:=false;
  127. end;
  128.  
  129.  
  130.  
  131.  
  132. end.
  133.  
  134.  


I asked our god rvk and here is his answer :


Quote
Ok, the problem is the FServer.Active := true;
That just starts the listening server and execution stops until a response is received.
So it's essentially a loop itself so you can remove the while not terminated again.
You need to add the DoTerminate again to be able to stop the FServer.


But the problem is, that the DoTerminate is never executed in the thread anymore.
(you can see that by putting showmessages or breakpoints in the right places)


I'm not familiar with the TFPHTTPServer in a thread.
You could try to stop the server directory instead of calling Terminate but that didn't work for me either.


The main question is : How to stop correctly the thread/server ?


Thanks  !!!!


rvk

  • Hero Member
  • *****
  • Posts: 2389
Re: TFPHTTPServer in a thread
« Reply #1 on: March 12, 2017, 10:19:04 pm »
Additionally we tried this:
Code: Pascal  [Select]
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. begin
  3.   // FServerThread.Terminate;
  4.   FServerThread.FServer.Active := False;
  5. end;
to stop the FServer in the thread directly in the hope execution will continue in the execute-function of the thread but it didn't.

So, how does one stop the execution of TFPHTTPServer.Active := True; ?

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus