Frage

Ich schreibe einen Socket-Server und Flash-Spiel-Client. Das Spiel erfordert Echtzeit-Befehle wie Bewegung und Drehen. Es ist wichtig, dass diese Befehle vom Server an den Client so schnell wie möglich gesendet werden, weil die anderen Kunden sonst viel mit dem sich bewegenden / Dreh Client desynchronisiert.

Dies ist ein Beispiel für das Problem durch die Nagle Arithmetik verursacht:

Hinweis . Den Befehl Tabelle unten sehen, wenn Sie möchten, verstehen, was diese Befehle bedeuten

Erstens ist das Schiff, das ich bewegte (vorwärts bewegt + rechts, vorwärts empfangen wurde, aber gerade nicht)

Der Client sendet Befehle:

84796: Sending data: 2#4
84796: Sending data: 2#2
84904: Sending data: 2#3
84904: Sending data: 2#0
86187: Sending data: 2#4
86188: Sending data: 2#2
86374: Sending data: 2#3
86404: Sending data: 2#0

Der Client empfängt Befehle:

79244: Raw receive: 3#3#4$
79244: New command: 3#3#4
79398: Raw receive: 3#3#2$3#3#3$3#3#0$
79399: New command: 3#3#2
79399: New command: 3#3#3
79399: New command: 3#3#0
80635: Raw receive: 3#3#4$
80635: New command: 3#3#4
80908: Raw receive: 3#3#2$3#3#3$3#3#0$
80908: New command: 3#3#2
80908: New command: 3#3#3
80908: New command: 3#3#0

„Moment“ ist ein seltsamer Begriff, der bedeutet nicht, was ich bin versucht zu sagen, aber hier scheint es, die Menge an Zeit in Millisekunden nach dem vorherigen Befehl

  1. vorwärts senden von Client A (Zeit: 0), erhalten durch Client B (Zeit: 0)

  2. rechts abbiegen senden von Client A (Zeit: 0), erhalten durch Client B (Zeit: 155)

  3. nicht mehr bewegen senden von Client A (Zeit: 108), erhalten durch Client B (Zeit: 0)

  4. Anschlag Wende senden von Client A (Zeit: 0), erhalten durch Client B (Zeit: 0)

  5. vorwärts senden von Client A (Zeit: 1283), erhalten durch Client B (Zeitpunkt 1236)

  6. rechts abbiegen senden von Client A (Zeit: 1), erhalten durch Client B (Zeit: 273)

  7. Stop-Bewegung senden von Client A (Zeit: 186), erhalten durch Client B (Zeit: 0)

  8. Anschlag Wende senden von Client A (Zeit: 30), erhalten durch Client B (Zeit: 0)

Dies ist die Befehlstabelle mit den Befehlen entsprechen:

Client-> Server

2# (movement info)
0) now not turning
1) now turning left
2) now turning right
3) now not moving
4) now moving forward

Server-> Client

3# (movement info)
[shipId]#
0) now not turning
1) now turning left
2) now turning right
3) now not moving
4) now moving forward

Also, was Sie sehen können, ist, dass die Befehle völlig desynched sind wegen „Nagle“. Dies bewirkt, dass der Stoppbewegungsbefehl von anderen Clients gleichzeitig als Startbewegungsbefehl empfangen werden, so dass dieser Spieler nicht bewegen.

Aus diesem Grunde muß ich diese Befehle in Echtzeit, so schnell wie möglich durch den TCP-Server senden werden. Eine einfache Lösung wäre, einfach Nagle abzuschalten. Allerdings habe ich gegoogelt (beachten Sie, dass sein Vorschlag über tcp Nachricht teilweise in meinem System implementiert hat aber nichts mit dem Timing) ein wenig und bemerkte zu tun, dass die Menschen unbedingt deaktivieren Nagle nicht empfehlen.

Ist es wahr, dass ich nicht den Nagle-Algorithmus für diese Sache deaktivieren sollte und stattdessen für eine andere Lösung aussehen sollte? Warum (nicht)?

Vielen Dank im Voraus. - Tom

War es hilfreich?

Lösung

Sie möchten TCP_NODELAY verwenden, um den Nagle-Algorithmus für die Steckdose auszuschalten. Es gibt Einstellungen in modernen Betriebssystemen auf einer systemweiten Basis zu deaktivieren, und das IS verpönt, aber es gibt Grund nicht, sollten Sie es nicht mit einer Steckdose tun, die Sie Ihnen niedrige Latenzzeiten benötigen KNOW auf .

setsockopt (TCP_NODELAY)

Andere Tipps

Wenn es so schnell wie möglich sein muss, sollten Sie UDP verwenden.

Beachten Sie jedoch, dass TCP bietet Garantie von Lieferung und um , während UDP keine zur Verfügung stellt.

Dieser Punkt scheint ein kritisch wichtiger Punkt in dieser Anwendung zu sein, so würden Sie Ihre eigene Bestätigung / Retry Befehl Ordnungsmechanismus oben haben Schicht.

Wenn Sie mit TCP halten wollen, werden TCP__NODELAY helfen. Als Ihr Spiel Fortschritte können Sie am erfordert einen Strom von Daten beenden, die TCP gut ohne TCP_NODELAY geeignet sein wird.

RFC1006 formalisiert einen Mechanismus für die Pakete über einen TCP-Stream zu senden.

Beachten Sie, dass Ihr Switch, Router, ISP swithcgear .... etc können alle auch ihre kleine schwarze Seele aus dem Leib Nagle. Die schmutzigen kleinen Tiere können Pakete lesen, so nehmen sie Freiheiten und schreiben sie manchmal ..

Werfen Sie einen Blick auf RTP (die über UDP läuft) für ein Netzwerk -survivable Ansatz.

Wenn Ihr Ziel ist die Schiffe die gleiche Sache auf am Ende haben, ist Bildschirm jeder tun, Sie gehen zu haben Position Updates zu senden. Sie können nicht davon ausgehen, nur weil Client A hat:

  • Turn Left
  • Warten 100ms
  • Stop drehen

, dass Client B wird die exakt gleiche 100ms Verzögerung sehen. Die Nagle-Pufferung nur macht dies noch extremer -. Aber es wird immer Jitter und unterschiedliche Verzögerungen

Sie müssen wirklich etwas senden, wie:

  • (I an Position X1 ist, Y1 mit Z1 Überschrift) links abbiegen
  • (I an Position X2 ist, Y2 mit Z2 Überschrift) Stoppen Drehen

Damit die Kunden sind ständig resynchronising.

Beachten Sie, dass Windows implementiert verzögerte ACK sowie Nagle. Dies kann Ihnen eine zusätzliche 200 ms Verzögerung bei einzelnen TCP-Nachrichten. Soweit ich weiß, kann man das nicht außer über einen Registrierungsschlüssel unter Windows ändern (und einem Hotpatch den Registrierungsschlüssel in einigen Fällen zu ermöglichen).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top