AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Long running Rest API Call mit THTTPClient
Thema durchsuchen
Ansicht
Themen-Optionen

Long running Rest API Call mit THTTPClient

Ein Thema von Christoph Schneider · begonnen am 27. Jun 2018 · letzter Beitrag vom 27. Nov 2018
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#1

Long running Rest API Call mit THTTPClient

  Alt 27. Jun 2018, 11:20
Ich benötige für einen Event von einem Rest-Server einen long running HTTP-Request.

Wie macht man das sauber mit Delphi Board mitteln?

Meine aktuelle Lösung läuft zwar nach einigem Probieren. Der Stop des Request geht leider nur auf die harte Tour mit einem Thread.Terminate und hinterlässt dann als Folge unschöne Memory Leaks.

Delphi-Quellcode:
type
  TMyRestAPI = class
  private
    fClient: THTTPClient;
    fStream: TMemoryStream;
    fReadPos: Int64;
    fOnReceiveData: procedure(const data: string) of object;
    procedure OnRecData(const Sender: TObject; AContentLength: Int64;
      AReadCount: Int64; var Abort: Boolean);
  public
    procedure StartRequest(const URL: string);
    procedure StopRequest;
  end;

procedure TMyRestAPI.StartRequest(const URL: string);
begin
  fClient := THTTPClient.Create;
  fClient.HandleRedirects := true;
  fClient.Accept := 'text/event-stream';
  fClient.OnReceiveData := OnRecData;
  fStream := TMemoryStream.Create;
  fReadPos := 0;
  fThread := TThread.CreateAnonymousThread(
    procedure
    begin
      fClient.Get(URL, fStream);
    end);
  fThread.Start;
end;

procedure TMyRestAPI.OnRecData(const Sender: TObject; AContentLength: Int64;
  AReadCount: Int64; var Abort: Boolean);
var
  ss: TStringStream;
  resp: string;
begin
  ss := TStringStream.Create;
  try
    fStream.Position := readPos;
    ss.CopyFrom(fStream, AReadCount - fReadPos);
    fOnReceiveData(ss.DataString);
    fReadPos := AReadCount;
  finally
    ss.Free;
  end;
end;

procedure TMyRestAPI.StopRequest;
begin
  fThread.Terminate;
  fClient.Free;
  fStream.Free;
end;
Da ich den Request alle paar Stunden repetitiv abbrechen muss um anschliessend mit einem neuen Token zu restarten, suche ich eine bessere Lösung.
Bei Verwendung der Asynchronen Calls mit BeginExecute/BeginGet lässt sich der laufende Request leider auch nur stoppen, wenn Daten vom Server empfangen werden.
Gerade dies ist aber bei einem long running rest API Call über längere Zeit hinweg nicht der Fall und ich fand kein Weg, den asynchrone Request zu einem beliebigen Zeitpunkt zu stoppen.

Async := fClient.BeginGet(URL); Meine Lösung sollte unter Firemonkey auf allen Plattformen laufen, dass wäre mindestens dass Ziel!
Christoph Schneider
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Long running Rest API Call mit THTTPClient

  Alt 27. Jun 2018, 11:29
Hast du dich bewusst gegen die REST-Komponenten (TRESTRequest, TRESTClient,TRESTResponse) entschieden?
http://docwiki.embarcadero.com/RADSt...ientbibliothek

(Was völlig okay wäre, um klein und schlank zu bleiben, aber ich wollte trotzdem fragen.)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.157 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Long running Rest API Call mit THTTPClient

  Alt 27. Jun 2018, 11:38
Siehe auch:
https://www.delphipraxis.net/192625-...erringern.html
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Long running Rest API Call mit THTTPClient

  Alt 27. Jun 2018, 13:12
(an den Thread musste ich auch denken...ist das schon wieder so lange her? )
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.157 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Long running Rest API Call mit THTTPClient

  Alt 27. Jun 2018, 13:33
So etwas bringt mich auch immer wieder aus der Fassung. Das Problem liegt bei mir übrigens immer noch in der Schublade, die Timeouts sind bis heute immer noch drin
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Long running Rest API Call mit THTTPClient

  Alt 27. Jun 2018, 13:56
Aber das liese sich doch mit den Intercepten der Windows-Funktionen doch problemlos umgehen.
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Long running Rest API Call mit THTTPClient

  Alt 27. Jun 2018, 19:02
Die Verwendung von Timeouts ist aus meiner Sicht keine praktikable Lösung für mein Problem. Ich müsste ein kurzes Timeout (1 Sek) wählen, um die Anforderung für eine gute Reaktion beim Beenden einzuhalten.
In der Folge möchte ich aber nicht alle Sekunden den Http-Request wieder neu starten müssen nur weil ich bei Beendigung des Programm nicht länger als eine Sekunde warten darf.

Ich brauche ich den long running Calls genau dafür, dass ich über längere Zeit den Stream offen halten kann und auf Ereignisse vom Server reagieren kann.
Klar könnte man dies theoretisch auch mit einem Polling machen, bei dem alle Sekunden ein Get-Request an den Server gesandt wird. Nur bedeutet dies enorm viel mehr Traffic, den ich vermeiden will.

Daher suche ich an einer Lösung, wie ich ein laufenden HTTP-Request bei Programm-Ende oder auf nach User-Interaktion sauber stoppen kann.

Die Delphi Rest-Komponenten setzt ja auch auf der THTTPClient (In TRESTHTTP ist FHTTPClient auch System.Net.HTTPClient.THTTPClient) und ich dachte mir, je näher ich an der Basis-Komponente bin, desto besser kann ich deren Verhalten steuern. Mit der TNetHTTPClient und Client.Asynchronous := true habe ich es bereits probiert. Hier kann ich den Request auch nicht schliessen, wenn keine Daten vom Server empfangen werden.

Wie machen denn andere long running rest API Calls? Und mit long running meine ich den Request eine Stunde oder länger offen zu halten und bei Bedarf wieder schliessen zu können.

@TiGü: Wie würdest Du das angehen mit Interceptoren vor und nach der WinApi-Funktion? Eigentlich wollte ich den HTTP-Requestnicht selber für alle Plattformen (mindestens Mac OS und Win32/64) implementieren aber vielleicht läuft es am Schluss doch auf eine solche Lösung raus.
Christoph Schneider

Geändert von Christoph Schneider (27. Jun 2018 um 19:06 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Long running Rest API Call mit THTTPClient

  Alt 27. Jun 2018, 19:25
Meine Idee mit den Interceptoren bezog sich ja auf das Timeout-Problem vom Günther.
Das bringt dir so also nichts.

Könntest du den lang offenen Request nicht in einen eigenen Prozess packen und den von deinen Hauptprogramm aus starten, steuern und ggf. killen?

Es gibt bestimmt noch eine elegantere Variante.
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Long running Rest API Call mit THTTPClient

  Alt 27. Jun 2018, 21:32
Mit einem eigenen Prozess wäre zwar das Memory Leak entschärft, dafür müsste eine Interprozesskommunikation (bpsw. mit einer Pipe) alle eintreffenden Meldungen an den startenden Prozess übermitteln. Da erscheint mir der Aufwand zum Ertrag (keine aufsummierenden Memory Leaks mehr) gar etwas hoch. Beide Lösungen (Thread Kill vs. Prozess Kill) sind ein Murks.

Aus meiner Sicht müsste es wenigstens auf Api Level möglich sein, ein gestarter HTTP Request vom aufrufenden Thread in allen Fällen (also auch ohne Empfang von Daten) jederzeit wieder zu stoppen.
Ich glaube, ich schaue jetzt mal wie das unter Windows gemacht werden könnte.

Danke für die vielen wertvollen Ideen.
Christoph Schneider
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Long running Rest API Call mit THTTPClient

  Alt 28. Jun 2018, 09:46
Hast du ein Beispiel für eine öffentliche REST-Schnittstelle mit long running requests?
Meine bisherigen Erfahrungen mit REST habe ich nur mit Schnittstellen gemacht, die innerhalb von einer handvoll Sekunden geantwortet haben.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:59 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