I have a problem which I can’t understand.
To understand it I wrote a socket client on AS3 and a server on python/twisted, you can see the code of both applications below.
Let’s launch two clients at the same time, arrange them so that you can see both windows and press connection button in both windows. Then press and hold any button.
What I’m expecting:
Client with pressed button sends a message “some data” to the server, then the server sends this message to all the clients(including the original sender) .
Then each client moves right the button ‘connectButton’ and prints a message to the log with time in the following format: “min:secs:milliseconds”.
What is going wrong:
The motion is smooth in the client that sends the message, but in all other clients the motion is jerky.
This happens because messages to those clients arrive later than to the original sending client. And if we have three clients (let’s name them A,B,C) and we send a message from A, the sending time log of B and C will be the same.
Why other clients recieve this messages later than the original sender?
By the way, on ubuntu 10.04/chrome all the motion is smooth. Two clients are launched in separated chromes.
Listing of log, four clients simultaneously:
[16:29:33.280858] 62.140.224.1 >> some data
[16:29:33.280912] 87.249.9.98 << some data
[16:29:33.280970] 87.249.9.98 << some data
[16:29:33.281025] 87.249.9.98 << some data
[16:29:33.281079] 62.140.224.1 << some data
[16:29:33.323267] 62.140.224.1 >> some data
[16:29:33.323326] 87.249.9.98 << some data
[16:29:33.323386] 87.249.9.98 << some data
[16:29:33.323440] 87.249.9.98 << some data
[16:29:33.323493] 62.140.224.1 << some data
[16:29:34.123435] 62.140.224.1 >> some data
[16:29:34.123525] 87.249.9.98 << some data
[16:29:34.123593] 87.249.9.98 << some data
[16:29:34.123648] 87.249.9.98 << some data
[16:29:34.123702] 62.140.224.1 << some data
AS3 client code, I left only relevant part, full code here.
private var socket :XMLSocket;
socket = new XMLSocket();
socket.addEventListener(DataEvent.DATA, dataHandler);
private function dataHandler(event:DataEvent):void
{
var now:Date = new Date();
textField.appendText(event.data + " time = " + now.getMinutes() + ":" + now.getSeconds() + ":" + now.getMilliseconds() + "\n");
connectButton.x += 2;
}
private function keyDownHandler(event:KeyboardEvent):void
{
socket.send("some data");
}
private function connectMouseDownHandler(event:MouseEvent):void
{
var connectAddress:String = "ep1c.org";
var connectPort:Number = 13250;
Security.loadPolicyFile("xmlsocket://" + connectAddress + ":" + String(connectPort));
socket.connect(connectAddress, connectPort);
}
You may be experiencing some combination of ACK delay and/or Nagle’s algorithm. Both of these can selectively delay the movement of data on a TCP session and their implementations vary greatly by platform.
Try using
setsockopt()withTCP_NODELAYon the socket to disable Nagle.AFIK, Windows does not let you disable ACK delay on a per socket basis: you must edit the registry and disable it for all TCP. So try
TCP_NODELAYfirst. If that does not work, then experiment with disabling ACK delay. Even if registry editing is not practical for your application, just knowing whether ACK delay is the problem can point you in the right direction for other work-arounds.