Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange Flash AS3 xml Socket behavior

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.

windows screenshot

linux screenshot

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);
        }

Python server code.

like image 785
Rnd_d Avatar asked Jan 20 '12 11:01

Rnd_d


2 Answers

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() with TCP_NODELAY on 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_NODELAY first. 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.

like image 75
Seth Noble Avatar answered Nov 19 '22 10:11

Seth Noble


I know this is a bit late, but most likely this is because of the time it takes to setup the TCP connection between the server and the non-initiating client.

The idea being that there is already a TCP connection established between the initiating client and the server (its set up prior to the first client's message), so the time it takes to conduct the 3 way handshake is eliminated in that case.

You could test this a few ways, the most easy being by establishing a connection before your real message handling (e.g. by sending a dummy message to each).

You could also switch to UDP if you don't want to setup a connection with each client, but then you lose the reliability of TCP.

I'm not sure I understood your note about Linux. Are you saying it works as intended on Linux but not Windows? If so, we'll need to know more about your setup, for example are all the clients running on the same host? In the same browser instance?

like image 42
jedwards Avatar answered Nov 19 '22 11:11

jedwards