Server Push mit fpHttpServer?

Alle Fragen zur Netzwerkkommunikation
Antworten
Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 168
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Server Push mit fpHttpServer?

Beitrag von Jorg3000 »

Hallo!
Ich bastele gerade an einer Intranet-Anwendung, die als Single-Page-Application aktuelle Daten per AJAX erhält.
Da kam mir natürlich der Wunsch nach Server Pushs, denn die Seite soll auch ohne Zutun des Users aktualisiert werden, wenn die Daten von einem anderen gleichzeitigen User geändert wurden.

Soweit ich sehe, unterstützt fpHttpServer das Protokoll HTTP/1.1, wobei 1.1 wohl noch keinen Server Push kennt (erst HTTP/2 und HTTP/3).

Deshalb war meine Idee, immer einen AJAX-Request geöffnet zu lassen und vom Server solange unbeantwortet zu lassen, bis der Server irgendwann mal neue Daten hat.
Sobald der Server sich zurückgemeldet hat, wird anschließend vom Browser gleich wieder eine neue Anfrage gestellt.
Falls sich auf dem Server nichts geändert hat, antwortet er z.B. nach 20 Sekunden "Keine neuen Daten", damit es nicht zu einem Time-out kommt.
Ist das praktikabel oder eine Scheißidee? (bevor ich es morgen anfange zu programmieren).

Im Web habe ich vorhin "Server-Sent Events" (SSE) gefunden, die wohl mit "herkömmlichem HTTP" funktionieren sollen, habe mich aber noch nicht eingelesen.
Hat jemand damit schon mal etwas gemacht?
Danke und Grüße, Jörg

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 168
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Server Push mit fpHttpServer?

Beitrag von Jorg3000 »

PS:
Da ich faul bin, habe ich eben ChatGPT nach "Server-Sent Events" gefragt. :D
Es hat mir ein Beispiel für die Client-Seite in JavaScript und für die Server-Seite in FreePascal geliefert.
Das schaut sehr gut aus. Ich werde es morgen mal einbauen - und wenn es funktioniert, poste ich hier ein lauffähiges Beispiel.
Grüße, Jörg

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Server Push mit fpHttpServer?

Beitrag von m.fuchs »

ChatGPT war jetzt leichter zu bedienen als Tante Google?

Je nachdem wie weit du es treiben willst, könnten Websockets eine Möglichkeit sein.
https://wiki.freepascal.org/Networking#LazWebsockets
https://github.com/Warfley/LazWebsockets
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Server Push mit fpHttpServer?

Beitrag von Warf »

Solang du deine Timeouts richtig konfigurierst ist das absolut kein Problem sein. Ich hatte auch mal so ein Ähnliches Protokoll gesehen, wo eigentlich Anfragen vom Server aus kommen, aber weil HTTP verwendet wurde musste das dann ein bisschen umgedreht werden, sodass zu beginn der Client ein Request mit der InitializeCommunication Message gesendet hat, und dann sobald der Server was abfragen wollte er darauf geantwortet hat mit der eigentlichen anfrage. Der client hat dann die Anfrage vom server in einem neuen HTTP Request beantwortet. Wenn der Server mehr wissen wollte konnte er dann als Antwort auf dieses HTTP Request die nächste Anfrage senden, oder aber eine CloseConnection Message, worauf hin der Client keine weiteren Anfragen mehr sendet.

Also in etwa so:

Code: Alles auswählen

(*
[C]                    [S]
 |                      |
 +----HTTPReq(Init)---->+
 |       [...]          |
 |<-HTTPResp(Req(id0))--|
 |--HTTPReq(Resp(id0))->|  
 |       [...]          |
 |<-HTTPResp(Req(id1))--|
 |--HTTPReq(Resp(id1))->|  
 |       [...]          | 
 |<--HTTPResp(Close))---|
*) 
Frag mich aber nicht welches Protokoll das war, oder wie lang die Zeiträume zwischen Request und Response in Wirklichkeit war. Ich glaub das war auch kein Ajax, sondern sowohl Client als auch Server waren Native Programme die nur HTTP als wrapper verwendet haben

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: Server Push mit fpHttpServer?

Beitrag von six1 »

Jorg3000 hat geschrieben:
Di 16. Mai 2023, 19:05
Hallo!
...
denn die Seite soll auch ohne Zutun des Users aktualisiert werden
...
Jorg, dies ist eine klassisches AJAX Anwendungsgebiet.
Ich habe dies in Microcontrollern als auch großen Dell Web-Servern eingesetzt, da man nicht die gesamte Seite neu laden muss, sondern nur Teile nachgeladen werden.
Its a kind of magic, wenn sich Werte auf einer Seite aktuallisieren, ohne weiteres Zutun des Anwenders; dies geht leicht mit Ajax.
Gruß, Michael

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Server Push mit fpHttpServer?

Beitrag von Warf »

Also WebSockets hat schon einen Vorteil gegenüber Ajax, denn HTTP hat einen ziemlich großen Overhead (vor allem HTTP/1.1), wenn also die Daten mit niedriger latenz geupdated werden sollen ist Ajax potentiell zu langsam. Ich hatte mal eine Webanwendung geschrieben bei der mit jedem Klick die Daten Serverseitig geändert werden müssen und danach der View geupdated werden. Hatte das am anfang mit Ajax gemacht, doch da war halt so viel Delay drin das es praktisch nicht benutzbar war.

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: Server Push mit fpHttpServer?

Beitrag von six1 »

ja Warf, wenn es aber wirklich nur Kleine Dinge sind, welche z.B. in ein <SPAN> nachgeladen werden, ist es doch vielleicht nur ein TCP Paket...
Ich denke hierbei z.B. an einen Javasript Timer, welcher über AJAX Messwerte nachlädt.
Sollten ganze Seitenteile nachgeladen werden, ist es natürlich mehr...
Gruß, Michael

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 168
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Server Push mit fpHttpServer?

Beitrag von Jorg3000 »

Moin!
Die Server-Sent Events (SSE) habe ich leider nicht zum Laufen gebracht. Es scheitert am fpHttpServer, weil ein Response-Objekt (TFPHTTPConnectionResponse) es nicht zulässt, mehrfach Daten zu senden.
Das Response-Objekt merkt sich, ob es schon mal etwas gesendet hat und unterbindet dann künstlich per Exception eine weitere Benutzung des Sockets. Schön fürs Debugging, schlecht für meine Absicht.
Die entsprechenden Properties sind protected. Ich habe alternativ versucht direkt auf den Socket zu schreiben, aber ich bediene das SSE-Protokoll anscheinend nicht richtig. Habe nun nach mehreren Stunden auch keine Nerven mehr, um mich weiter damit rumzuärgern.

Habe es nun stattdessen Javascript-seitig mit einem Interval und Ajax-Requests gelöst. Das ist zwar total unelegant, funktioniert aber auf Anhieb. Damit bin ich jetzt erst mal zufrieden.
Grüße, Jörg

Antworten