Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Message an alle Terminal-Server-Sitzungen senden (https://www.delphipraxis.net/205854-message-alle-terminal-server-sitzungen-senden.html)

Papaschlumpf73 23. Okt 2020 14:21

Message an alle Terminal-Server-Sitzungen senden
 
Hallo Gemeinde,

für einem Windows Terminal Server habe ich einen Windows-Dienst mit einem Mini-Webserver entwickelt. Dieser überwacht einen speziellen Port der lokalen IP-Adresse und empfängt typisierte Nachrichten von anderen Servern. Soweit so gut.

Auf dem Server sind nun i.d.R. ca. 20 User via RDP/Citrix angemeldet und arbeiten gleichzeitig auf diesem Server. Eine andere Anwendung von mir läuft in diesen 20 Sitzungen quasi gleichzeitig.

Jetzt soll mein mini Webserver die empfangene Nachricht an alle 20 Sitzungen bzw. an alle aktiven Instanzen meiner Anwendung auf diesem Server senden. Anhand der Nachricht kann dann eine der aktiven Instanzen meiner Anwendung darauf reagieren.

Ich könnte natürlich den Dienst in eine Datei oder die Registry schreiben lassen und die 20 Instanzen meiner Anwendung lesen diese permanent aus. Das finde ich aber nicht besonders elegant.

Daher möchte ich gerne, dass der Windows-Dienst eine Nachricht an alle User-Sitzungen auf diesem Server sendet. Wer weiß wie das geht???

himitsu 23. Okt 2020 14:32

AW: Message an alle Terminal-Server-Sitzungen senden
 
IPC? (Bei Google suchenInter-process communication : Messages, Pipes, Semaphore, Mutex, Event, MailSlot, TCP, ...)

CreateEvent, WaitFor...
PostMessage (Broadcast ... aber weiß grade nicht ob es zu anderen Benutzern nutzbar ist)
https://stackoverflow.com/questions/...ser-in-windows
TCP/IP bzw. UDP

Rollo62 23. Okt 2020 16:04

AW: Message an alle Terminal-Server-Sitzungen senden
 
Es müssten doch alle Clients eine eigene IP-Adresse haben, oder nicht ?
Dann könntest du allen einen UDP-Broadcast schicken (der aber nicht iimmer 100% sicher ankommen muss).

https://www.mcseboard.de/topic/46255...ressen-client/
https://docs.microsoft.com/en-us/win...oninformationa
v

Entweder direkt mit Daten, oder einfach einen generellen Braodcast der denen sagt das es was Neues zum Abholen gibt.

mjustin 23. Okt 2020 16:41

AW: Message an alle Terminal-Server-Sitzungen senden
 
Zitat:

Zitat von Papaschlumpf73 (Beitrag 1476037)
Daher möchte ich gerne, dass der Windows-Dienst eine Nachricht an alle User-Sitzungen auf diesem Server sendet. Wer weiß wie das geht???

Da alle Client-Sessions auf dem gleichen Server laufen, können sie über die IP Adresse 127.0.0.1 oder localhost theoretisch einen Port öffnen, z.B. deinen Mini-Webserver, und auf eine bestimmte Resource per HTTP GET Request zugreifen, z.B.

GET /localhost:80/messages

Der Server antwortet dann mit einer HTTP Response, die entweder eine Nachricht oder einen leeren Body (Payload) hat.

Das ist das Prinzip 'Long Polling': der Client sendet in einer Schleife den GET-Befehl. Der Server blockiert, falls es für den Client aktuell keine neue Nachricht gibt, für eine gewisse Zeit (z.B. zehn Sekunden), bevor er die Antwort sendet. Das vermeidet unnötige CPU Last.

Technisch benötigt der Client dann eine minimale HTTP-Client Implementierung, entweder die vom Betriebssystem bereitgestellte oder eine Komponente wie TIdHttp.

himitsu 23. Okt 2020 20:12

AW: Message an alle Terminal-Server-Sitzungen senden
 
Via TCP die Clienten sich mit dem Serve verbinden, ja

Bei UDP ... alle Clienten haben die selbe IP und müssten dann unterschiedliche Ports haben.
(weiß nicht ob alle Clients auf dem selben UDP-Port lauschen können)
Wenn der Server dann alle Ports einzeln ansprechen muß, dann lohnt sich UDP nicht wirklich.

Papaschlumpf73 23. Okt 2020 22:12

AW: Message an alle Terminal-Server-Sitzungen senden
 
Vielen Dank für die vielen Vorschläge. Hier eine kurze Zwischennachricht nach ein paar Tests - das hier funktioniert leider alles nur innerhalb einer Session:

Delphi-Quellcode:
WM_BroadCast:=RegisterWindowMessage('WM_BroadCast')
SendMessage(HWND_BROADCAST,...
Postmessage(HWND_BROADCAST,...
BroadcastSystemMessage(BSF_POSTMESSAGE,...
SendNotifyMessageA(HWND_BROADCAST,...
ChangeWindowMessageFilter(...) --für 2 processe, die innerhalb einer Session mit unterschiedlichen Privilegien gestartet wurden

Papaschlumpf73 23. Okt 2020 22:20

AW: Message an alle Terminal-Server-Sitzungen senden
 
Zitat:

Zitat von himitsu (Beitrag 1476047)
Via TCP die Clienten sich mit dem Serve verbinden, ja

Bei UDP ... alle Clienten haben die selbe IP und müssten dann unterschiedliche Ports haben.
(weiß nicht ob alle Clients auf dem selben UDP-Port lauschen können)
Wenn der Server dann alle Ports einzeln ansprechen muß, dann lohnt sich UDP nicht wirklich.

Das werde ich morgen mal ausprobieren.

Die anderen Vorschläge mit TCP kommen leider nicht infrage, da in den einzelnen Sessions keine eigenen IP-Adressen verfügbar sind; alle Sessions nutzen dieselbe IP-Adresse. Wenn jedoch jede Session dieselbe IP-Adresse mit einem anderen Port verwendet, bekommen wir wohl Schwierigkeiten mit den Firewallregeln.

HolgerX 24. Okt 2020 06:21

AW: Message an alle Terminal-Server-Sitzungen senden
 
Hmm..

Deine Clients verbinden sich mit deiner ServerApp per TCP und tauschen Daten aus.
-> Verbindung besteht von mehreren Clients auf einen Server, der die selben IP und Port hat.
-> Klappt auch, wenn die Clients auf dem selben Rechner mit der selben IP laufen..

Das geht, weil jeder Client automatisch einen anderen Port als Quellport verwendet!

Bleibt die Verbindung dann offen und wird nicht geschlossen, dann kann der Server jederzeit etwas an die verbundenen Clients schicken. Hierzu verwendet er die Quellport-Nummer als Zielport (selbe IP bei Terminal-Sessions).

Die Firewall solltest Du eh anpassen:
Wenn Du dort statt IP/Port die Applikation (Server Exe und Client EXE) angibst, dann können bei diesen die Ports wechseln, wie sie wollen. Ist halt dann nur eine Regel in der Firewall je App EXE.

dummzeuch 24. Okt 2020 09:44

AW: Message an alle Terminal-Server-Sitzungen senden
 
Um mal eine simple Lösung vorzuschlagen: Der Server legt irgendwo eine Datei an, die die anderen Programme regelmäßig abfragen.

Dabei ist die Datei vom Server mit allow read und deny write geöffnet und wird regelmäßig mit Timestamp neu geschrieben, so dass die Clients eine veraltete Datei erkennen und ignorieren können.

Ist old fashioned, aber funktioniert eigentlich immer.

Papaschlumpf73 24. Okt 2020 14:38

AW: Message an alle Terminal-Server-Sitzungen senden
 
Meine Anwendung bekommt jetzt eine idTCPClient-Kompo und der Mini-HTTP-Server-Dienst bekommt noch eine idTCPServer-Kompo dazu. Sobald meine Anwendung in einer WTS-Session gestartet wird, meldet sie sich beim TCPServer an und lässt die TCP-Verbindung offen. Erhält der HTTP-Server jetzt eine Anforderung sendet der TCP-Server diese über die bestehende TCP-Verbindung an die Client-Session, die die Anforderung dann tatsächlich bearbeiten soll. Ich hoffe nur, die TCP-Verbindungen klappen nicht nach ein paar Stunden zusammen, wenn da mal keine Daten kommen...

himitsu 24. Okt 2020 21:35

AW: Message an alle Terminal-Server-Sitzungen senden
 
Abgesehn davon, dass HTTP auch TCP nutzt.

Wenn die Server-App bereits einen HTTP-Server besitzt, dann könnten auch die Clienten via HTTP drauf zugreifen, wenn du da mit Keep-Alive rumspielst, da die Verbindung ja offen bleiben muß, damit der Server später die Antwort senden kann.

MyRealName 26. Okt 2020 09:11

AW: Message an alle Terminal-Server-Sitzungen senden
 
Also man könnte rein theoretisch von einem Session-unabhängigen Service durch die aktuell verbundenen Sessions durchgehen und dort einen Prozess starten, der dann jeweils im Kontext der Session läuft.

Papaschlumpf73 26. Okt 2020 17:19

AW: Message an alle Terminal-Server-Sitzungen senden
 
Zitat:

Zitat von MyRealName (Beitrag 1476099)
Also man könnte rein theoretisch von einem Session-unabhängigen Service durch die aktuell verbundenen Sessions durchgehen und dort einen Prozess starten, der dann jeweils im Kontext der Session läuft.

Das wäre super - ich hab aber keine Ahnung wie das geht.

himitsu 26. Okt 2020 18:15

AW: Message an alle Terminal-Server-Sitzungen senden
 
Du hast doch bereits Programme in den Sessions am laufen.
Somit ist es nicht nötig nochmal was zu starten, mit denen dann ebenfalls der Server irgendwie reden müsste. ;)

Papaschlumpf73 26. Okt 2020 18:34

AW: Message an alle Terminal-Server-Sitzungen senden
 
Zitat:

Zitat von himitsu (Beitrag 1476137)
Du hast doch bereits Programme in den Sessions am laufen.
Somit ist es nicht nötig nochmal was zu starten, mit denen dann ebenfalls der Server irgendwie reden müsste. ;)

Mit der TCP-Client-Server-Konstruktion klappt es auch ganz gut. Ich versuche es nur immer so einfach wie möglich hinzubekommen.

MyRealName 27. Okt 2020 06:59

AW: Message an alle Terminal-Server-Sitzungen senden
 
Man müsste halt wissen, was du mit der Message machen willst.. weiter verarbeiten oder einfach einen Dialog anzeigen wie "der server wird in 5 minuten runtergefahren"..

Papaschlumpf73 27. Okt 2020 08:15

AW: Message an alle Terminal-Server-Sitzungen senden
 
Zitat:

Zitat von MyRealName (Beitrag 1476156)
Man müsste halt wissen, was du mit der Message machen willst.. weiter verarbeiten oder einfach einen Dialog anzeigen wie "der server wird in 5 minuten runtergefahren"..

Meine Anwendung muss jeweils die Nachricht auswerten, bestimmte Daten von der Datenbank abrufen und dem Anwender bestimmte Reaktionen darauf anbieten. Eine einfache MessageBox reicht da leider nicht aus. Eine solche Windows-Funktion ist mir auch schon bei der Suche nach einer Lösung über den Weg gelaufen.

MyRealName 27. Okt 2020 08:29

AW: Message an alle Terminal-Server-Sitzungen senden
 
Da wäre eine Lösung wie Websockets (da bidirektional) auch ganz gut.. oder eben Indy. Beim Start einfach beim Service anmelden... Ich selbst nutze für sowas RealThinClient, aber ist halt kommerzielles Paket. Vorteil : Schnelle und einfach Implementierung und Datenaustausch über JSON

Papaschlumpf73 27. Okt 2020 08:34

AW: Message an alle Terminal-Server-Sitzungen senden
 
Zitat:

Zitat von MyRealName (Beitrag 1476166)
Da wäre eine Lösung wie Websockets (da bidirektional) auch ganz gut.. oder eben Indy. Beim Start einfach beim Service anmelden... Ich selbst nutze für sowas RealThinClient, aber ist halt kommerzielles Paket. Vorteil : Schnelle und einfach Implementierung und Datenaustausch über JSON

Mit den Indys klappt es schon super. Es werden auch nur kurze Kommandos mit einer ID ausgetauscht; da wäre JSON schon der Holzhammer. Und in Websockets müsste ich mich erst einmal einarbeiten... Ich bin zu alt für das neumodische Zeug :-D:-D

lxo 27. Okt 2020 15:51

AW: Message an alle Terminal-Server-Sitzungen senden
 
Wenn die Clients mit einer gemeinsamen Datenbank verbunden sind, könntest du das ja auch evtl. über Events aus der Datenbank regeln.
Firebird hat da aufjedenfall was zu.https://firebirdsql.org/file/documen...ird_events.pdf
Ich denke andere DBMS werden auch was ähnlich haben. Kenne die anderen Systemen leider nur nicht ganz so gut.


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