AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Server-Antwort an mehrere Clients senden mit Indy
Thema durchsuchen
Ansicht
Themen-Optionen

Server-Antwort an mehrere Clients senden mit Indy

Ein Thema von Harry Stahl · begonnen am 16. Jun 2015 · letzter Beitrag vom 18. Jun 2015
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Harry Stahl
Harry Stahl
Online

Registriert seit: 2. Apr 2004
Ort: Bonn
2.532 Beiträge
 
Delphi 11 Alexandria
 
#1

Server-Antwort an mehrere Clients senden mit Indy

  Alt 16. Jun 2015, 16:32
Ich habe mal eine Frage zur Optimierung:

Ich habe in einer Client-Server Anwendung die Notwendigkeit, dass der Server eine Nachricht, die er von einem Client erhalten hat (Im OnExeCute-Event einer TidTCPServer-Komponente) an andere Clients im Netzwerk senden muss (mittels einer TidTCPClient-Komponente).

Bislang habe ich das so gemacht, dass in einem Extra-Thread nacheinander die entsprechenden Clients über die TCPClient-Komponente, die ich noch im Programm habe, unterrichtet wurden.

Nun ist es aber heutzutage so, dass zunehmend Clients über WLAN oder Internet mit dem Server verbunden sind. Da gibt es dann schon mal längere Antwortzeiten. Ich muss also einen relativ hohen Connection-Timeout Wert verwenden, um dem Rechnung zu tragen. Dadurch kann die Sache aber u.U. relativ lange dauern, bis alle Clients unterrichtet wurden.

Wäre es eine denkbare Variante, mehrere Threads zu erzeugen, wo dann lokal entsprechende TCPIPClient-Komponenten erzeugt werden und dann jeder einzelne Thread versucht, seine Nachricht zu versenden?

Oder ist das eine schlechte Idee? Evtl. weil es Beschränkungen bei den ausgehenden TCP/IP-Verbindungen pro PC gibt? Dass dann der gleiche Sendeport von mehreren TCPClient-Komponenten verwendet werden müsste, kann doch eigentlich kein Problem sein, oder (im Gegensatz zum Empfang beim Server, da geht das ja nicht)?
  Mit Zitat antworten Zitat
Benutzerbild von Valle
Valle

Registriert seit: 26. Dez 2005
Ort: Karlsruhe
1.223 Beiträge
 
#2

AW: Server-Antwort an mehrere Clients senden mit Indy

  Alt 16. Jun 2015, 17:26
Wäre es eine denkbare Variante, mehrere Threads zu erzeugen, wo dann lokal entsprechende TCPIPClient-Komponenten erzeugt werden und dann jeder einzelne Thread versucht, seine Nachricht zu versenden?
Ja, sicher!

Oder ist das eine schlechte Idee? Evtl. weil es Beschränkungen bei den ausgehenden TCP/IP-Verbindungen pro PC gibt? Dass dann der gleiche Sendeport von mehreren TCPClient-Komponenten verwendet werden müsste, kann doch eigentlich kein Problem sein, oder (im Gegensatz zum Empfang beim Server, da geht das ja nicht)?
Wie viele zehntausende Verbindungen planst du denn gleichzeitig?

Das ist kein Problem und völlig normales Vorgehen. Du kannst die Menge an gleichzeitigen Verbindungen auf einen sinnvollen Wert* beschränken indem du das Thread-Pool Designmuster verwendest. Kurz gesagt: du hältst mehrere laufende Threads vor, die eine Queue abarbeiten. Die Threads laufen auch, wenn die Queue leer ist, um Latenzen gering zu halten. Du füllst die Queue mit Aufgaben (in dem Fall senden einer Nachricht) und die Threads arbeiten die Queue ab. Achte bei der Queue auf Thread-safety. Vorsichtig muss man auch mit den Sockets sein. Es sollte immer nur ein Thread einen Client bedienen.

* Ein sinnvoller Wert ist schwierig zu nennen. Moderne Linux-Server schaffen problemlos sehr viel mehr Verbindungen als du vermutlich brauchen wirst. Das lastet den Server aber natürlich allgemein ziemlich aus. Ich würde mal mit ~10 beginnen. Nimm ruhig mehr, wenn du es für nötig hältst. Ab ~1000 würde ich über einen Designwechsel nachdenken.
Valentin Voigt
BOFH excuse #423: „It's not RFC-822 compliant.“
Mein total langweiliger Blog
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl
Online

Registriert seit: 2. Apr 2004
Ort: Bonn
2.532 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Server-Antwort an mehrere Clients senden mit Indy

  Alt 16. Jun 2015, 18:47
Danke, cool, das hört sich ja gut an.

Na, es werden normalerweise nur ein paar Dutzend Verbindungen benötigt, aber sobald ein WLAN dazwischen ist, das nicht so gut funktioniert, könnte das schon eine grundsätzliche Beschleunigung ausmachen.

Werde ich mal testen und dann auch noch mal rückmelden.

Erst mal Danke für die Antwort, das war sehr hilfreich. Denn so muss ich nicht etwas ausprobieren, was am Ende nicht funktionieren würde.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Server-Antwort an mehrere Clients senden mit Indy

  Alt 16. Jun 2015, 19:02
Und wenn dir dann der Server zuviel herumrödelt, dann kannst du ja auch mal eine vernünftige statt einer normalen Lösung versuchen

Die vernünftige heisst dann Long Polling oder Push oder .... In allen Fällen meldet sich der Client beim Server, fragt nach neuen Informationen und signalisiert damit dem Server auch seine Empfangsbereitschaft.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl
Online

Registriert seit: 2. Apr 2004
Ort: Bonn
2.532 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Server-Antwort an mehrere Clients senden mit Indy

  Alt 16. Jun 2015, 19:14
Ja, Polling verwende ich schon in einer anderen Client/Server Anwendung, wollte ich hier jetzt auch einbauen.

Das ist der mir einzig bekannte Ausweg, wenn man nur über eine ausgehende Verbindung zu einem außerhalb des Netzwerkes stehenden Servers (z.B. Internet) verfügt und wo mehrere Rechner im Netzwerk hinter einem Router sind und der Router per NAT nicht die Weiterleitung managt.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl
Online

Registriert seit: 2. Apr 2004
Ort: Bonn
2.532 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Server-Antwort an mehrere Clients senden mit Indy

  Alt 16. Jun 2015, 19:57
COOOOOOOOOL!!! Was für eine Verbesserung!!

Erzeuge jetzt für jede Nachricht, die an einen Client zu senden ist, einen eigenen Thread mit eigener lokalen TidTCP-Komponente.

Während bei der vorherigen Lösung der letzte Client die Nachricht z.B. nach 3 Sekunden erhielt, erhalten jetzt alle Clients die Nachricht nahezu gleichzeitig (bei ca. 10 Rechnern im gemixten Lan / WLAN Netz). Ich sitze hier oben auf dem Dachboden, da ist das Netz manchmal trotz Repeater nicht ganz so flink (außerdem sind Frau und Tochter auch im Netz, Spotify und Co. belasten das Netz dann halt schon mal ein wenig).

Ist insgesamt auch stabiler, da der einzelne Thread nun mehrmals den Sendeversuch starten kann, wenn es beim ersten mal nicht funktioniert haben sollte.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Server-Antwort an mehrere Clients senden mit Indy

  Alt 16. Jun 2015, 22:25
Eine andere Möglichkeit wären non-blocking Sockets. Da braucht man nicht für jeden Client einen Thread.

Eigentlich macht auch erst dann ein Thread-Pool Sinn. Wenn z.B. jede Operation eine Sekunde blockt, dann kannst du mit blockierenden Sockets selbst mit einem Threadpool mit 8 Threads nur mickrige 8 Operationen pro Sekunde machen, während du mit non-blocking Sockets in der gleichen Zeit vielleicht locker 1000 Operationen schaffen würdest, sogar völlig ohne Multithreading.

Also wenn man schon blockierende Sockets verwendet, dann muss man auch für jede Verbindung einen eigenen Thread haben.
  Mit Zitat antworten Zitat
Benutzerbild von Valle
Valle

Registriert seit: 26. Dez 2005
Ort: Karlsruhe
1.223 Beiträge
 
#8

AW: Server-Antwort an mehrere Clients senden mit Indy

  Alt 17. Jun 2015, 00:44
"einen eigenen Thread mit eigener lokalen TidTCP-Komponente"? Ich hatte dich da wohl etwas falsch verstanden bei deiner Beschreibung. Kannst du nochmal erklären was genau dein Vorgehen jetzt ist?

Erstellst du von den Clients aus immer eine zweite Verbindung zum Server?
Oder öffnet der Server eine neue Verbindung zum Client (und der Client ist damit auch ein Server)?

Mein Gedanke ging mehr in die Richtung, die Namenloser andeutete. Alles geht über eine Verbindung. Wenn du Indy verwendest, dann nimmst du pro Verbindung einen Thread. Mit einer Queue kannst du die Menge an Threads minimieren. Über diese eine, einzige Verbindung pro Client gehen alle Daten.

Non-blocking ist gerade sehr in Mode und bietet deutliche Performance-Vorteile. node.js ist ein populär Vertreter für ganze non-blocking Frameworks. Das war auch mein Gedanke, als ich oben von "Designwechsel" sprach. Allerdings ist es bei Servern mit wenigen hundert Clients bei ordentlicher Implementierung noch gar kein Problem, egal welche Methode du verwendest.
Valentin Voigt
BOFH excuse #423: „It's not RFC-822 compliant.“
Mein total langweiliger Blog
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl
Online

Registriert seit: 2. Apr 2004
Ort: Bonn
2.532 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Server-Antwort an mehrere Clients senden mit Indy

  Alt 17. Jun 2015, 02:23
"einen eigenen Thread mit eigener lokalen TidTCP-Komponente"? Ich hatte dich da wohl etwas falsch verstanden bei deiner Beschreibung. Kannst du nochmal erklären was genau dein Vorgehen jetzt ist?

Erstellst du von den Clients aus immer eine zweite Verbindung zum Server?
Oder öffnet der Server eine neue Verbindung zum Client (und der Client ist damit auch ein Server)?
Der Client fragt beim Server, nach einer Information, oder ob er irgendetwas tun darf. Mit der gleichen Verbindung erhält der Client die Rückantwort.

Wenn der Client aber dem Server neue oder geänderte Daten übermittelt, dann muss der Server die anderen Clients davon unterrichten, bzw. diesen die Änderungen mitteilen. Nur in diesen Fällen öffnet der Server auch eine Verbindung zu den Clients (und insofern arbeiten die Clients dann als Server).

Wenn 10 User im Netz 10 Änderungen machen, muss der Server 90 Nachrichten an die Clients versenden.

Und diese Übermittelung an die Clients habe ich nun in einzelne Threads ausgelagert. Allerdings in eine pro Client angelegte TThreadList, welche die Nachrichten nach dem FirstIn / FirstOut Prinzip abarbeitet. Arbeitet nach erstem Augenschein schnell und zuverlässig.

Non-blocking ist gerade sehr in Mode und bietet deutliche Performance-Vorteile. node.js ist ein populär Vertreter für ganze non-blocking Frameworks. Das war auch mein Gedanke, als ich oben von "Designwechsel" sprach. Allerdings ist es bei Servern mit wenigen hundert Clients bei ordentlicher Implementierung noch gar kein Problem, egal welche Methode du verwendest.
Das werde ich gerne mal ansehen, wenn ich ein wenig mehr Zeit habe. Da bei meinen Programmen i.d.R. max. 50 Anwender im Netz gleichzeitig mit einer DB arbeiten, dürfte das mit Indy noch lange Zeit reichen.
  Mit Zitat antworten Zitat
Bambini
(Gast)

n/a Beiträge
 
#10

AW: Server-Antwort an mehrere Clients senden mit Indy

  Alt 17. Jun 2015, 10:51
Wenn der Client aber dem Server neue oder geänderte Daten übermittelt, dann muss der Server die anderen Clients davon unterrichten, bzw. diesen die Änderungen mitteilen. Nur in diesen Fällen öffnet der Server auch eine Verbindung zu den Clients (und insofern arbeiten die Clients dann als Server).
Dies werden die Firewalls auf den Clients erst mal nicht erlauben.
  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 21:28 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