2012-11-14 9 views
11

In Bezug auf JavaScript & PHP WebSocket TCP Paket verklumpen, mit Beispiel unten.WebSocket TCP-Pakete verklumpen?

Aus irgendeinem Grund, wenn Pakete schnell auf meinem VPS gesendet werden oder auf meinen Localhost über eine Domäne zugreifen, die auf meine IP-Adresse verweist, werden mehrere Pakete zusammengeballt. Ich versuche, für dieses Beispiel 20 (@ 100byte) Pakete pro Sekunde zu streamen. Auf der Server-Seite werden sie tatsächlich mit einer konstanten Geschwindigkeit ausgesendet, genau alle 50 ms, was 20 pro Sekunde macht. Wenn sie jedoch zum Client gelangen, verarbeitet der Client nur etwa jede 1/4 Sekunde neue Nachrichten. Wenn neue Pakete nur mit einer Rate von 4 pro Sekunde oder so empfangen werden ...

Was verursacht dieses Verklumpen von Paketen zusammen? Dieses Problem tritt nicht auf, wenn alles über localhost erfolgt. Was noch seltsamer ist, ist, dass es reibungslos auf iOS Mobile Safari von iPhone läuft, ohne irgendein Problem. ABER, es funktioniert überhaupt nicht auf PC Safari, (weil ich nicht eingerichtet habe, richtig mit dem alten Hixie-76 WebSocket-Format zu arbeiten, gehe ich davon aus, dass Mobile Safari bereits das neuere RFC 6455 oder neuere JavaScript verwendet Compiler) Ich habe mehrere Hosting-Unternehmen ausprobiert, mit genau den gleichen Ergebnissen jedes Mal.

Siehe das Beispiel unten, auf InMotion des VPS Gastgeber: http://www.hovel.me/script/serverControl.php

(Klicken Sie auf [Connect] auf der linken Seite, dann [Ansicht Spiel] auf der rechten Seite).

Das aktuelle empfangene Paket springt jedes Mal um 5, da alle 5 Pakete gleichzeitig alle 1/4 Sekunde empfangen werden. Ich habe jedoch Beispiele gesehen, die einen konstanten, schnellen Paketstrom senden können. Was bewirkt, dass dieses Zusammenklumpen/Pakete aufeinander warten?

EDIT: Das hat etwas mit Nagle's algorithm zu tun sein, die zusammen & sendet kleine Pakete sammelt? Ich werde versuchen, dies in PHP zu umgehen. Selbst mit diesem in PHP gesetzten TCP_NODELAY bleibt das Problem bestehen. Warum funktioniert es auf einem iPhone, aber nicht auf einem PC wirft mich immer noch ...
EDIT: Festlegen von TCPNoDelay und TcpAckFrequency auf 1 in der Registrierung behebt dies, aber ich kann nicht erwarten, dass jeder Benutzer das tun. Es muss eine Client-Seite, Brot & Butter JavaScript-Weg sein.

Wie kann ich Funktionalität replizieren node.js' "socket.setNoDelay(true)", ohne node.js mit?

Antwort

3

Das ist TCP. Es hilft Ihnen, indem Sie IP-Pakete sparen. Ein Teil davon ist auf den Nagle-Algorithmus zurückzuführen, aber ein Teil davon kann auch durch das Zwischennetzwerk verursacht werden.

+0

Es ist sinnvoll, aber nicht für Echtzeit-Streaming, und WebSocket unterstützt derzeit UDP nicht, so dass ich für jetzt fest damit bin. Ich weiß, dass es einen Workaround gibt, aber das Einstellen von TCP_NODELAY (das Deaktivieren von Nagles Algorithmus) durch PHP hat es für mich noch nicht gelöst. Danke für Ihre Hilfe – TheWandererLee

3

Am Ende hat der Client, der den Nagle-Algorithmus nicht deaktiviert hat, zusammen mit seiner Bestätigungsfrequenz, die immer noch bei ungefähr 200 ms gesetzt ist, bewirkt, dass das Zwischennetzwerk die folgenden Pakete in einem Puffer hält. Manuell eine Bestätigungsnachricht an den Server sendet aus, bewirkt jedes einzelne Mal, erhält der Kunde eine Nachricht, um das Netzwerk zu sofort „wake-up“ und weiterhin die nächsten Pakete zu verarbeiten, im Gegensatz sie in einem Puffer zu halten.

Beispiel:

conn = new WebSocket(url); 
conn.onmessage = function(evt){ 
    Server.send('ACKNOWLEDGE BYTES'); // Send ACK to server immediately 
    dispatch('message', evt.data); //Do regular event procedures 
}; 

Diese temporäre Lösung funktioniert jedoch dies nahezu verdoppeln Bandbreitennutzung unter anderem Netzwerkprobleme. Bis ich den WebSocket auf dem Client-Ende richtig nicht für die Server-Bestätigung "in den Standby-Modus" bringen kann und das Netzwerk Nachrichten sofort durchstößt, werden dadurch die Pakete schneller ohne das Problem des Verkorkens des Puffers durchlaufen.