AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Indy-Test optimieren
Thema durchsuchen
Ansicht
Themen-Optionen

Indy-Test optimieren

Ein Thema von stahli · begonnen am 25. Apr 2014 · letzter Beitrag vom 28. Apr 2014
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von stahli
stahli

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

Indy-Test optimieren

  Alt 25. Apr 2014, 00:38
Hallo zusammen,

nachfolgendes ist nur etwas für Leute mit starken Nerven - bzw. mit Kenntnissen von Indy und ausreichend Tagesfreizeit

Also: Ich habe ein kleines Testprojekt (XE3)...


Server:
Ein Server verwaltet ein Integer-Array und stellt die Werte als Linien in einem Bitmap dar, das über einen Timer in das Formular kopiert wird.
Die Werte werden durch das Array geschoben, um einen optischen Effekt zu haben.
Klick in das Formular dreht die Darstellung jeweils um 90 Grad.

Das Array und der Turn(Dreh)-Wert sind einfach mal global verwaltet und reine Integer, damit es keine Syncro-Probleme gibt.


Clients:
Die Clients haben die gleiche Datenstruktur und Darstellung.
Aber über Indy werden nacheinander zyklisch alle Zahlenwerte und der Turn-Wert abgerufen.
Dieser Abruf läuft in einem Thread, damit das Formular "bedienbar" bleibt.
Ein Formular-Click sendet in dem Fall einen Dreh-Auftrag an den Server.


Die Werte-Übertragung läuft über Streams (mit Umweg über eine StringList), damit optional auch Umlaute übertragen werden könnten.


Im Grunde funktioniert das soweit - ABER!
Das ist natürlich recht langsam und die Clients bleiben gelegentlich auch hängen.


Ich weiß, dass ich in dem Testprojekt VIELES falsch mache. Aber zumindest das globale Array bitte ich hier mal großzügig zu übersehen.
Mir geht es hier darum, den Datenaustausch zwischen Server und Client zu optimieren und stabil zu gestalten.

Real soll der Server eine Menge von Daten verwalten, von denen sich die Clients nach Bedarf einige abrufen bzw. auch Aufträge den Server senden.
Über einen abzurufenden Zeitstempel können die Clients prüfen, ob der Server über neue Daten verfügt. Wenn nicht, werden gepufferte Daten genutzt.
Hier im Beispiel will ich diese Prüfungen vernachlässigen.

Wenn es gelingt, die Grafik in den Clients flüssig aktualisieren zu lassen wäre ich schon sehr zufrieden.

Bei Indy würde ich eigentlich gern bleiben, da man so ja auch noch andere Möglichkeiten wie eMail usw. hätte.
Es wäre aber auch ein genereller Wechsel möglich, wenn das etwas bringen würde.


Drei Hinweise noch:
- natürlich will ich nicht das Bitmap vom Server an die Clients schicken
- und die Clients können nicht wissen, welche Werte sich auf dem Server geändert haben.
- Die realen Daten können auch Sonderzeichen und Umlaute enthalten


Wäre super, wenn sich das jemand mal anschauen könnte...

Anbei
- Video
- XE3-Projekt
- Exen (in den Ini´s müsstet Ihr am besten Eure IP eintragen)

(Sorry, ist halt ziemliches Stückelwerk.)
Angehängte Dateien
Dateityp: zip NetCalc-Video.zip (3,19 MB, 21x aufgerufen)
Dateityp: zip NetCalc-XE3.zip (217,5 KB, 17x aufgerufen)
Dateityp: zip NetCalc-Exen.zip (1,80 MB, 12x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  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
 
#2

AW: Indy-Test optimieren

  Alt 25. Apr 2014, 01:01
Was hast du denn für ein Problem mit den Strings und Umlauten und Streams?

Dafür gibt es Hilfsklassen (z.B. Delphi-Referenz durchsuchenTStreamWriter/Delphi-Referenz durchsuchenTStreamReader) und schwupps sind die Daten im Stream und wieder aus dem Stream.
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 stahli
stahli

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

AW: Indy-Test optimieren

  Alt 25. Apr 2014, 10:38
(ich muss das jetzt mal aus der Erinnerung zusammen fassen)

Socket.Writeln(' Text mit é ') führte immer zu einer Verstümmelung. Je nachdem welche Textart ich angegeben habe (UTF8 o.ä.) wurden auch Umlaute verstümmelt. Eine fehlerfreie Textübertragung mit Sonderzeichen und Umlauten habe ich nicht hin bekommen.

Daher der Weg über Streams.

TStreamReader und TStreamWriter waren mir nicht mehr geläufig.
Andererseits hatte ich auch überlegt, die Anweisung und Parameter ohnehin als StringList zu übertragen:
Zitat:
Anweisung
Param1
Param2
Param3
So hätte man dann leichteren Zugriff auf die einzelnen Parameter.

Meine wichtigere Frage wäre aber die Gestaltung des Datenaustausches gewesen. Das ist sicher noch sehr suboptimal, insbesondere wenn mehrere Clients Daten abrufen.

Wie machen das denn Onlinespiele?
Im Grunde könnte man ja die laufenden Linien als Spielfiguren ansehen und die Clients rufen ab, welche Linie (oder Figur) jetzt wo und wie gezeichnet werden muss.

Meine Lösung ist einfach viel zu langsam und ich weiß nicht, wie man das besser gestalten könnte.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (25. Apr 2014 um 13:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.487 Beiträge
 
Delphi 7 Enterprise
 
#4

AW: Indy-Test optimieren

  Alt 25. Apr 2014, 11:26
Was ist denn nun genau langsam? Der Server, die Clients oder was? Ich habe mir jetzt nur den Server angeschaut. Da kann man schon Einiges optimieren. Aber das wäre ehe "Feintuning". Versuch doch mal herauszufinden, in welchen Routinen / Zeilen am meisten Zeit verbaten wird.
Als erstes würde ich aber auf das Ganze auf UDP umstellen, da Du sonst den ganzen Protokoll-Ballast mitschleppst. Es sein denn Du willst mal irgendwas tunneln oder es womöglich als http tarnen.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  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
 
#5

AW: Indy-Test optimieren

  Alt 25. Apr 2014, 12:28
Bei einem Online-Spiel können die Daten extrem reduziert werden.

Ein Objekt (Spieler, Rakete, Baum) ist vom Aussehen und Verhalten klar definiert und wird wenn nötig am Anfang des Spiels einmal übertragen (Farben, Polygone, Texturen, ...)

Bei Änderungen werden nur noch Position und Status übertragen und nicht das gesamte Objekt.

z.B. Rakete fliegt mit folgendem Bewegungsvektor [x,y,z] von Position [x,y,z]
und nur weil die Rakete weiterfliegt, werden keine neuen Daten übertragen, denn das Flugverhalten ist bekannt und kann ohne weitere Daten von jedem Client berechnet werden.
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 stahli
stahli

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

AW: Indy-Test optimieren

  Alt 25. Apr 2014, 12:47
@Sir Rufo

Ja aber ich habe im Beispiel auch nur 300 Zahlenwerte.


@Union

Was genau so langsam ist habe ich noch nicht gecheckt. Ist im Zusammenspiel zwischen Server und Clients wohl auch nicht ganz so einfach.
Vielleicht ist das zeitliche Verhalten ja auch in Ordnung und gar nicht mehr gravierend zu verbessern. Dann wäre mein ursprüngliches Ziel auf dem Wege wohl nicht zu erreichen.
Es hätte natürlich auch sein können, dass mein Server oder die Clients grundsätzlich falsch aufgebaut sind.

UDP ist ja offenbar eine fehleranfälligere Übertragungsform. Fehler müssten dann also explizit geprüft und ausgebessert werden.
Würde das deutliche Geschwindigkeitsvorteile bringen?

Eigentlich muss die Datenübertragung zuverlässig im lokalen Netz und evtl. auch über Internet funktionieren. Genauere Anforderungen habe ich derzeit nicht.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.487 Beiträge
 
Delphi 7 Enterprise
 
#7

AW: Indy-Test optimieren

  Alt 25. Apr 2014, 15:38
Warum versuchen denn sämtliche Programme, die schnell und viele Daten übertragen müssen, unbedingt alles auf UDP umbiegen (z.b. Skype)? Das bringt gewaltige Vorteile im Bereich der Übertragung. Im lokalen Netzwerk macht es sich nicht ganz so gravierend bemerkbar.

Noch mal mein Vorchlag: Die Teile sind ja momentan noch winzig. Also hast Du gute Chancen die Bremsen zu finden durch exakte Messung. Schau Dir mal System.Diagnostics an.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#8

AW: Indy-Test optimieren

  Alt 25. Apr 2014, 16:21
Warum versuchen denn sämtliche Programme, die schnell und viele Daten übertragen müssen, unbedingt alles auf UDP umbiegen (z.b. Skype)?
Weil diese Programme (Skype, Videostreams) keine Probleme haben wenn mal ein Paket nicht ankommt - ein Ruckler oder ein Knacksen aufgrund eines fehlenden Datensatzes stört nicht so sehr, dass man deswegen die Übertragung sofort stoppen und die fehlende Millisekunde noch mal vom Server anfordern muss.
Michael Justin
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.487 Beiträge
 
Delphi 7 Enterprise
 
#9

AW: Indy-Test optimieren

  Alt 25. Apr 2014, 16:34
Man braucht die Pakete für die Clients nur durchnumerieren. Die dann zu implementierende Prüfungslogik ist trival. Aber stahli sollte das trotzdem zunächst mal profilen - unabhängig vom Übertragungsprotokoll.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#10

AW: Indy-Test optimieren

  Alt 25. Apr 2014, 20:31
Nun, die erste Optimierungsmöglichkeit die auffällt ist:

anstatt für jeden einzelnen Integerwert eine Verbindung zu Server aufzubauen, einen Request zu senden, den Integerwert abzuholen (mit S := ReadText(IdTCPClient1, '?' + IntToStr(Index));) und dann die TCP Verbindung zu schliessen, nur einmal pro Zyklus die Verbindung aufbauen und einen kompletten Datenblock (300 Integerwerte) abrufen. Und die Verbindung nur nach einem Datenblock schliessen, oder nur bei Fehlern und beim Programmende.

Ein potentieller Störfaktor ist das "fForm.Caption := DateTimeToStr(Now);", das ist ein nicht-threadsicherer Zugriff auf ein Objekt der Oberfläche.
Michael Justin

Geändert von mjustin (25. Apr 2014 um 21:13 Uhr)
  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 06:15 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