Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Indy TIdHTTPServer OnGet: Aufruf von Funktionen mit Paramete (https://www.delphipraxis.net/48741-indy-tidhttpserver-onget-aufruf-von-funktionen-mit-paramete.html)

DocE 29. Jun 2005 20:38


Indy TIdHTTPServer OnGet: Aufruf von Funktionen mit Paramete
 
Hallo zusammen!

Ich habe folgendes Problem:

Der Indy HTTP Server erstellt anscheinend für jede Verbindung einen eigenen Thread und übergibt diesen in z.B. OnCommandGet als AThread. Also müßte man mit Synchronize arbeiten. Wie übergebe ich jedoch mit Synchronize Parameter oder erhalte results? Ein einfaches Beispiel:

LoadMemo liegt auf dem Hauptformular, genau wie der HTTPServer.

Delphi-Quellcode:
  LoadMemo.Clear;
  LoadMemo.Lines.LoadFromFile('test.html');
  AResponseInfo.ContentText := LoadMemo.Text;
Dies führt jedoch zu Exceptions wie "Text überschreitet Memo-Kapazität". Daher müßte man dies mit AThread.Synchronize aufrufen. Wie kann ich ihm jedoch den Parameter ('test.html') übergeben und wie bekomme ich das entsprechende result (hier: LoadMemo.Text);

In diesem Fall kann man natürlich mit einem zur Laufzeit erzeugten TMemo arbeiten. Dies ist unproblematisch. Jedoch ist das Problem komplexer:

Ich führe je nach übergebenen "Document" eine bestimmte Prozedur/Funktion am Server aus, die u.a. mit Querys Datenbankoperationen durchführt. Da hier gelegentlich Fehler auftauchen, die ich mir nicht erklären kann, führe ich diese auf die Thread-Problematik zurück. Wie kann man also Prozeduren und Funktionen mit Parameter innerhalb dieses OnGet-Threads aufrufen?

Macht evtl. ein extra Formular Sinn, auf dem die Querys liegen und welches dann von jedem Thread zur Laufzeit dynamsich erzeugt (not visible), die entsprechenden Funktionen ausgeführt und anschließend freigegeben wird? Ist ein solches Formular dann "Thread sicher"?

Ich bin sicher, Ihr wißt eine Lösungsmöglichkeit.

Vielen Dank.

MfG
..DocE

Sanchez 29. Jun 2005 20:44

Re: Indy TIdHTTPServer OnGet: Aufruf von Funktionen mit Para
 
Hallo,
Wenn du Parameter und Ergebnisse über Synchronize austauschen willst, dann musst du über Hilfsvariablen arbeiten.
In deinem konkreten Fall würde das so aussehen:
Delphi-Quellcode:
private
  FHTMLDatei : string;
  FErgebnisText : string;
...
  FHtmlDatei := 'test.html';
  Synchronize(LadeDateiInVariable);
  AResponseInfo.ContentText := FErgebnisText;
...

procedure TKlasse.LadeDateiInVariable;
begin
  LoadMemo.Lines.LoadFromFile(FHtmlDatei);
  FErgebnisText := LoadMemo.Lines.Text;
end;
grüße, daniel

DocE 29. Jun 2005 20:55

Re: Indy TIdHTTPServer OnGet: Aufruf von Funktionen mit Para
 
Hallo Daniel,

danke für Deine Antwort.

Das Problem ist, dass der HTTPServer und das Memo auf einem Formular liegen. Diese Variablen würden ja ebenfalls zu dem Formular gehören und wären wiederum nicht Thread-sicher. Ich erzeuge ja nicht explizit einen eigenen Thread, sondern TidHTTPServer tut es, um OnCommandGet aufzurufen. Damit wären diese variablen wohl nicht "sicher". Es könnte ja passieren, dass ein zweiter Thread die Variable bereits geändert hat, bevor Synchronize aufgerufen wird, oder?

Ich habe gerade mal folgendes ausprobiert, was zu funktionieren scheint:

in dem OnCommandGet-Event:
Delphi-Quellcode:
procedure TMainForm.HTTPS2CommandGet(AThread: TIdPeerThread;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var TestForm: TTestForm;
begin

  Application.CreateForm(TTestForm,TestForm);
  AResponseInfo.ContentText := TestForm.LoadFromFile('test.html');
  try TestForm.Free; except end;

end;

TTestForm hat dann die Funktion
Delphi-Quellcode:
function TTestForm.LoadFromFile(FileName: string) : string;
begin

  LoadMemo.Clear;
  LoadMemo.Lines.LoadFromFile(FileName);
  result := LoadMemo.Text;

end;
Hier scheint es keine Probleme zu geben. Oder birgt diese Lösung Gefahren, die ich an dieser Stelle übersehe?

MfG
..DocE

Sanchez 29. Jun 2005 21:14

Re: Indy TIdHTTPServer OnGet: Aufruf von Funktionen mit Para
 
Wenn du diese beiden Variablen sonst nirgendwo verwendest, dann sind sie threadsicher.
Sollten sie noch irgendwo anders z.B. im Hauptthread benutzt werden, dann solltest du Zugriffe durch eine CriticalSection regeln.

grüße, daniel

DocE 29. Jun 2005 21:48

Re: Indy TIdHTTPServer OnGet: Aufruf von Funktionen mit Para
 
Oh, "CriticalSection" sagt mir jetzt nicht so viel. Müßte ich mich nochmal umschauen.

Werden denn diese Paramter (z.B. im private Bereich des Hauptformulars deklariert), nicht von allen OnCommandGet-"Threads" benutzt? So dass eine zweite (fast zeitgleiche) Anfrage an den Server zu Komplikationen führen würde?

Moment, ich probiere das gerade mal aus...

Gibt Probleme. Habe folgenden Code getestet:


Delphi-Quellcode:
private
    TempString: string;
    TempCounter: Integer;

(...)

procedure TForm1.HTTPS2CommandGet(AThread: TIdPeerThread;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin

  inc(TempCounter);
  TempString := inttostr(TempCounter);
  Sleep(5000); // um zeitgleiche Zugriffe zu simulieren, 2. Aufruf in dieser Zeit
  AResponseInfo.ContentText := TempString;

end;
Hier erhalte ich bei beiden Browsern die Rückgabe "2". Da ja der zweite Thread (2 Sekunden später gestartet) die Variable TempString in der Wartezeit auf 2 setzt.

MfG
..DocE

Sanchez 29. Jun 2005 21:53

Re: Indy TIdHTTPServer OnGet: Aufruf von Funktionen mit Para
 
Zitat:

Zitat von DocE
Werden denn diese Paramter nicht von allen OnCommandGet-"Threads" benutzt?

Ach ja, genau. Ich hatte ganz übersehen, dass du mehrere Threads hast.
Da solltest du jeden Zugriff auf diese Variablen durch CriticalSections schützen. Die OH sollte dir alles Wissenswerte (= Enter und Leave) über diese Klasse verraten.

grüße, daniel


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:17 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