AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Spielwiese - SocketTest
Thema durchsuchen
Ansicht
Themen-Optionen

Spielwiese - SocketTest

Ein Thema von stahli · begonnen am 7. Okt 2016 · letzter Beitrag vom 24. Mär 2017
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#1

Spielwiese - SocketTest

  Alt 7. Okt 2016, 21:10
Hi,

im Bereich "Tutorial" wäre es nicht korrekt aufgehoben, daher mal hier...


Ich habe ein Testprojekt (XE3) mit ServerSocket und ClientSocket erstellt.

Es gibt einen "ClientManager", der die Mausereignisse erhält und mit dem Server kommuniziert und als Ergebnis ein Bitmap erstellt, das im Formular dargestellt wird.
Die Clientlogik läuft also in dem Manager und das Formular dient nur als grafische und Ereignisschnittstelle.

Im Servermanager auf der anderen Seite läuft eine eigenständige "Businesslogik" in einem eigenen Thread.
Änderungen in der Datenschicht (hier testweise alle paar Millisekunden) werden an die Clients geschickt, die die Daten empfangen und ein neues Bitmap erstellen.

So hält der Server einen kompletten Datenbestand und die Clients zeichnen sich entsprechend der übertragenen Daten.

Ein wenig könnte man das vielleicht mit einem simplen Spiel vergleichen.


Der Anwendungsfall macht natürlich wenig Sinn, aber
- ich habe zwei konkrete Fragen, die Ihr vielleicht beantworten könnt
- vielleicht können wir die Struktur der Anwendung verbessern und die mit Sicherheit vorhandenen problematischen Teile optimieren.
- vielleicht ist das ja für andere mal von Interesse
- evtl. könnte man auch ein etwas ernsthafteres Projekt daraus weiterentwickeln (vielleicht ein kleines Netzwerkspiel für die DP oder das von Mavarik angedachte Ameisenprojekt?) um daran weiter zu lernen - nur so eine Idee...


Meine Fragen:
1) Bei mir arbeitet der Server oft deutlich (10-30 mal) langsamer als normal, wenn die Delphi-IDE geschlossen ist. Starte ich die IDE, läuft er wieder normal, schließe ich sie, ist er wieder langsamer. Das ist jedoch nicht immer so (im verlinkten Video z.B. nicht). Kann das jemand einordnen?
2) Ich erhalte einen "asnchronen Fehler" vom ServerSocket, wenn ein Client geschlossen wird.
Das Problem liegt darin, dass die in einem eigenen Thread laufende "Businesslogik" ständig (alle paar ms) Änderungsmeldungen an alle Clients verschickt. Ich habe zwar versucht, diese mit dem Mainthread zu synchronisieren, aber das reicht nicht.
Der zu schließende Socket hat wohl schon die Kill-Nachricht vom Server, befindet sich aber noch einen Moment in der Socketliste und wird somit vom BL-Thread noch mit beim Nachrichtenversand berücksichtigt. Das führt dann zu einem Fehler.
Ich finde keine Möglichkeit, die Kill-Nachricht rechtzeitig zu erkennen und somit keine Rundumnachricht mehr an den Kill-Socket zu senden.
Kann da jemand helfen?


Anbei das XE3-Projekt.
Die Bibliothekspfade müsste man bei Bedarf einrichten, so dass die Nachnutzung leider etwas aufwendiger wird (ggf. kann ich dazu noch eine Übersicht erstellen, was erforderlich wäre).
Die Exen sind in den Release-Ordnern. In den Ini´s könnte man andere Ports und für die Clients andere IPs eintragen (habe ich aber noch nicht getestet).

Hier ein Link zu einem Video: https://youtu.be/mnoBtkIzEf4
(Sind aber 18 min, also lohnt sich nur, wenn Ihr direktes Interesse am Thema habt.)

Bin gespannt, ob das für irgendwen von Interesse ist...
Angehängte Grafiken
Dateityp: jpg sockettest1.jpg (32,6 KB, 103x aufgerufen)
Angehängte Dateien
Dateityp: zip SocketTestKurzesVideo.zip (843,1 KB, 26x aufgerufen)
Dateityp: zip SocketTest.zip (1,90 MB, 42x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli ( 8. Okt 2016 um 15:10 Uhr) Grund: einige Sekunden Videauszug als Zip angehängt
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Spielwiese - SocketTest

  Alt 9. Okt 2016, 19:46
Mal eine neuere Version.

Die IP und Port in der Ini wird jetzt auch berücksichtigt.
(Ich war wohl doch zu übermüdet.)

Die Exen werden jetzt zentral unter D:\SocketTest erzeugt. Das ist m.E. übersichtlicher.


Ich habe das jetzt auch über WLAN und Internet getestet.
Der Server schickt 4*360 Änderungen pro Sekunde an die Clients.
Lokal sieht das flüssig aus. Über Netzwerk hakelt es natürlich.

Natürlich ist das nicht optimiert, aber es soll ja auch mal ein Stresstest sein.

Als nächstes will ich mal protokollieren, ob alle Daten bei den Clients ankommen oder ob welche verloren gehen.
Kann ja ein einfacher Integer sein, der laufend erhöht wird.
Werde ich nächste Woche mal tun.

Dann will ich auch prüfen, wie die Sockets sich im blockierenden Modus verhalten.
Angehängte Dateien
Dateityp: zip SocketTestProject.zip (254,2 KB, 24x aufgerufen)
Dateityp: zip SocketTest.zip (1,66 MB, 23x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

AW: Spielwiese - SocketTest

  Alt 10. Okt 2016, 11:39
Als nächstes will ich mal protokollieren, ob alle Daten bei den Clients ankommen oder ob welche verloren gehen.
Darüber brauchst du dir keine Gedanken machen. TCP garantiert sowohl die korrekte Reihenfolge als auch die verlustfreie Zustellung der Pakete
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Spielwiese - SocketTest

  Alt 10. Okt 2016, 11:58
... oder was es für Probleme geben kann, wenn der Server massenweise Nachrichten verschickt und die Clients nicht hinterherkommen würden.

Wie gesagt, ich kann diese ganzen Grenzfälle nicht wirklich einordnen und werde das daher mal "am eigenen Leib" versuchen...
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
747 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Spielwiese - SocketTest

  Alt 10. Okt 2016, 12:17
Hallo stahli

Wenn du dich nur auf eigene Mittel verlassen willst, dann lass doch den Server in gewissen Abständen (zum Beispiel abhängig von der Zeit oder von der Menge der gesendeten Daten) eine Nachricht [Inhalt: Sendezeit] an den Client senden, welche der Client rausfischt und an den Server zurücksendet. Dann weisst du relativ genau, wie schnell/gut deine Leitung ist.

Gruss
M
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Spielwiese - SocketTest

  Alt 11. Okt 2016, 21:20
Ich bin hin und her gerissen ... aber multidimensional!


Erst mal zu einem festgestellten Problem:

Nicht blockierende Sockets unterhalten sich ungeordnet.
Aus drei gesendeten Texten
Text1
Text2
Text3
kann auf der Empfängerseite
Text1Text2Text3
werden.

Im Screenshot 1 sieht man, dass die eigentlich einzeln gesendeten Stringlisten auf der Gegenseite verbunden ankommen. Möglicherweise werden sie u.U. auch mittendrin geteilt, das habe ich nicht untersucht.

Man muss somit klare Trennzeichen definieren:
Text1*
Text2*
Text3*
würde dann
Text1*Text2*Text3*
und könnte wieder zerlegt werden
oder
man könnte bei übertragenen Stringlisten festlegen, wie viele der nächsten Zeilen zu einem command gehören:
3
SetXY
10
10
2
SetName
stahli


Also man braucht genaue Regeln, damit man sie wieder ordentlich trennen bzw. zusammenfügen kann, ehe man sie verarbeitet.



Was aber gravierender ist, ist dass die Reihenfolge bzw. der Zeitpunkt der Textsendungen nicht klar vorherzusehen ist (siehe Screenshot2). Es ist insofern nachvollziehbar, da ja für den Mainthread Messages erzeugt werden, die dann nach und nach abgearbeitet werden.

Wenn ich also in meiner Demo vielfach pro Sekunde automatisch Daten vom Server verschicke (und vielleicht von Clients aus zwischendurch auch noch Rückfragen starte), werden die Clients mit Messages bombardiert und sind voll beschäftigt, diese abzuarbeiten. Von 1000 Zwischenständen werden somit 999 gar nicht sinnvoll berücksichtigt oder es werden 100 Rückfragen in Form von Messages "gesammelt", obwohl dies natürlich nur einmal sinnvoll wäre.
Entsprechend muss man entweder die Frequenz reduzieren oder auf Clientseite feststellen, dass gerade nur der letzte erhaltene Zwischenstand relevant ist - oder beides.
Eine Rückfrage bezüglich einer bestimmten Information dürfte nicht nochmal rausgehen, sofern schon eine gleichartige erzeugt wurde und noch nicht beantwortet ist. Das müsste somit extra verwaltet werden, da man schlecht die WindowsMessageQueue durchsuchen kann (oder diese vielleicht gerade schon unterwegs zum Server ist).


Ein Chatbeispiel ist für non blocking Sockets sicherlich gut geeignet, nicht aber unbedingt ein Projekt, das auf Serverseite ständig neue Änderungen erzeugt oder erzeugen kann und viele Clients darüber informieren will.

Wenn man dies mit non blocking Sockets realisieren will muss der Server am besten für jeden Client verwalten, wann dieser zuletzt über welche Änderungen informiert wurde und Änderungsmitteilungen etwas verzögert und optimiert versenden.

Der Client dürfte seinerseits nicht sofort neue Daten abrufen sondern müsste auch schauen, wann ein guter Zeitpunkt dafür ist und den Status aller Anfragen intern selbst verwalten - obwohl die Antwort über Windows-Nachrichten kommt.

Also so etwas ist sicherlich möglich, aber kann sicher sehr schnell sehr aufwendig werden.



Jetzt könnte man natürlich auf den blockierenden Modus umstellen, aber dann kann ich ja auch bei den Indys bleiben, mit denen ich eine funktionierende Kommunikation schon im Griff hatte.
Ich hatte mir nur gedacht, dass ich mit den nicht blockierenden Sockets performanter bin und halt ohne pulls auskomme.

Schicken die non blocket sockets eigentlich interne Pulls und erzeugen letztlich auch eine Last auf dem Netzwerk und der CPU?
Oder sind Pulls aller 1/2 Sekunde von den Clients schon teurer?


Long Pulls über Threads wären natürlich auch denkbar, aber da würde ich doch regelmäßige kurze Pulls bevorzugen, in denen Zeitstempel abgerufen werden.


Wenn man ein Projekt jetzt doch mit den non blocket sockets aufbaut, könnte man das Projekt dann grundsätzlich irgendwie auf andere Plattformen übertragen?
Sicherlich doch nicht, da man dann ja an die Windows Messages gebunden ist - oder?



Mein Zwischenfazit ist derzeit, dass die Indys wohl doch keine so schlechte Lösung sind und man eben mit zyklischen Pulls oder LongPulls leben muss.

Weiteres Fazit ist, dass es scheinbar kein vernünftiges Tutorial gibt, das diese ganzen Zusammenhänge mal beleuchtet...
Angehängte Grafiken
Dateityp: png st1.png (66,1 KB, 52x aufgerufen)
Dateityp: png st2.png (115,1 KB, 57x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.405 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Spielwiese - SocketTest

  Alt 12. Okt 2016, 17:41
1) Bei mir arbeitet der Server oft deutlich (10-30 mal) langsamer als normal, wenn die Delphi-IDE geschlossen ist. Starte ich die IDE, läuft er wieder normal, schließe ich sie, ist er wieder langsamer. Das ist jedoch nicht immer so (im verlinkten Video z.B. nicht). Kann das jemand einordnen?
Wie ich gerade erst gelernt habe liegt das an timeBeginPeriod, das von Delphi benutzt wird um die minimale Timerauflösung herunterzusetzen. Dadurch kehrt Sleep schneller zurück, insbesondere, wenn Sleep(1) oder so benutzt wird.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Spielwiese - SocketTest

  Alt 12. Okt 2016, 19:02
@mjustin

Mein realer Anwendungsfall sieht eher so aus, dass die Clients sich Daten gezielt beim Server abholen, und zwar danach, was sie gerade anzeigen sollen.

Also der eine Client stellt die Kundenliste dar, und nach einem Pagewechsel jetzt den Fahrplan der DB.
Ein anderer Client zeigt ein Kochrezept an.

Sie sagen jeweils dem Server, was sie gerade brauchen, puffern das und stellen die Daten dar.

Ein anderer Client Ändert jetzt irgend etwas in der Datenschicht. Z.B. wird ein Kunde hinzugefügt.

Derzeit ändert (in meinem Realprojekt, nicht in der Demo hier) der Server einen Zeitstempel auf Now.
Die Client fragen regelmäßig, den aktuellen Serverzeitstempel ab.
Wenn der jetzt neuer ist als bei der letzten Abfrage holen sie sich die o.g. Daten (bzw. die, die sie gerade darstellen) neu vom Server ab und zeichnen die GUI neu. Das heißt, einen Moment werden noch die Daten aus dem Puffer angezeigt (oder wenn nicht vorhanden leere Controls oder Zellen) und nach der Aktualisierung umgehend die neuen Daten.

Da das als lazy loading abläuft gibt es ein paar kurze Verzögerungen, die ich noch etwas optimieren wollte.


Das heißt, dass die Clients sich im Regelfall schon ganz bestimmte Informationen abrufen müssen.
Ein automatischer Rundruf vom Server könnte sich eigentlich auf ein "Es gibt neue Daten!" beschränken.


Insofern war die Demo hier etwas missverständlich zu meiner echten Zielstellung. Ich wollte hier nur mal den Server testweise extrem beschäftigen
... und habe festgestellt, dass dies nicht so funktioniert wie ich erwartet hatte.


So wie ich Message Broker inzwischen verstanden habe wären die für meine reale Zielstellung eher nicht hilfreich (da die Clients ja direkt bestimmte Daten nach ihren individuellen Bedürfnissen abfordern bzw. gezielte Änderungen an bestimmten Daten initiieren).




@jaenicke
Ok, danke!



EDIT: Idee ... Oh Ich versuche da mal was. Kann ein paar Tage dauern...
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (12. Okt 2016 um 19:25 Uhr)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#9

AW: Spielwiese - SocketTest

  Alt 12. Okt 2016, 19:29
So wie ich Message Broker inzwischen verstanden habe wären die für meine reale Zielstellung eher nicht hilfreich (da die Clients ja direkt bestimmte Daten nach ihren individuellen Bedürfnissen abfordern bzw. gezielte Änderungen an bestimmten Daten initiieren).
Tja, ich habe ja noch nicht alle Möglichkeiten der Message Broker dargestellt, um keinen Informations-Overkill zu bewirken

Die meisten Message Broker unterstützen auch Kommunikation in der Art eines Remote Procedure Calls (RPC). Dazu erzeugt jeder Client einen individuellen, nur für ihn gültigen Nachrichtenkanal auf dem Server (der beim Verbindungsende gelöscht wird). Dann sendet der Client seine spezielle Message an einen Nachrichtenkanal (zum Beispiel: "ich brauche das Rezept für Boeuf Stroganoff"). Und innerhalb dieser Nachricht gibt der Client an, dass er die Antwort auf seinem individuellen Kanal erwartet. Der Message Broker leitet die Nachricht an den Delphi Server weiter, schlägt das Rezept nach, und sendet es los.

So kann ein Message Broker individuelle Anfragen der Clients an den Delphi Server weiterleiten, und die Antworten an den richtigen Client zurück senden.

Dabei bleibt der große Vorteil des Message Brokers erhalten, dass der Delphi Server nur eine einzige Socket-Verbindung zu Message Broker aufbaut. Unabhängig von der Zahl der Clients, deren RPC Requests er beantwortet.
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Spielwiese - SocketTest

  Alt 30. Okt 2016, 18:38
Ok, hier mal das Projekt (XE3 und Exen) und ein neues Video: https://youtu.be/6MBQD-HJLGw

Das Video dauert 40 min. Es ist also sicher nur interessant für diejenigen, die an asynchroner Kommunikation direktes Interesse haben.
(Dies ist übrigens mein 4. Aufnahmeversuch gewesen, da ich bei vorherigen Versuchen diverse Probleme und Abbrüche bis hin zu einem BlueScreen hatte. Also bitte seht mir nach, wenn es nicht so ganz strukturiert ist. Der Nerv-Faktor war schon etwas erhöht. Notfalls kann ich ja nochmal nachliefern.)

Ich denke, der Ansatz könnte ganz tauglich sein.
Aber sicher sind noch einige Bugs und Optimierungsmöglichkeiten vorhanden.

Auch das Problem mit dem gelegentlichen Fehler beim Abmelden eines Clients konnte ich noch nicht vollständig lösen.


Da ich das Konzept jetzt mal in einem anderen Projekt umsetzen will würde mich mal interessieren, was Ihr dazu meint und wer daran auch selbst Interesse hat.
Insbesondere ist natürlich interessant, wenn Ihr hier Probleme erkennt bzw. Lösungen für diese habt.


Natürlich ist das Projekt recht komplex und umfangreich, aber wenn wir eine stabile Version erreichen könnte das m.E. ein sehr nützliches Package für eine allgemeine und einfache asynchrone Kommunikation werden.


Es wäre also nett, wenn Ihr mal Rückmeldungen bezüglich Interesse und Verbesserungen gebt.


Gruß Stahli
Angehängte Dateien
Dateityp: zip soMessageTransfer.zip (265,2 KB, 22x aufgerufen)
Dateityp: zip soMessageTransferRun.zip (1,72 MB, 21x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  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 16:22 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