Странное поведение Flash AS3 xml Socket - PullRequest
6 голосов
/ 20 января 2012

У меня есть проблема, которую я не могу понять.

Чтобы понять это, я написал сокет-клиент для AS3 и сервер на python / twisted, вы можете увидеть код обоих приложений ниже.

Давайте запустим два клиента одновременно, расположим их так, чтобы вы могли видеть оба окна, и нажмите кнопку подключения в обоих окнах.Затем нажмите и удерживайте любую кнопку.

Что я ожидаю:

Клиент с нажатой кнопкой отправляет сообщение «некоторые данные» на сервер, затем сервер отправляетэто сообщение всем клиентам (включая исходного отправителя).

Затем каждый клиент перемещает вправо кнопку «connectButton» и печатает сообщение в журнал со временем в следующем формате: «min: secs: milliseconds».

Что идет не так:

Движение плавное на клиенте, который отправляет сообщение, но на всех других клиентах движение прерывистое.

Это происходит потому, что сообщения этим клиентам приходят позже, чем первоначальному отправляющему клиенту.И если у нас есть три клиента (назовем их A, B, C) и мы отправим сообщение от A, журнал времени отправки B и C. будет таким же.

Почему другие клиенты получаютэто сообщения позже, чем у исходного отправителя?

Кстати, на ubuntu 10.04 / chrome все движение плавное.Два клиента запускаются в отдельных цветах.

снимок экрана Windows

снимок экрана linux

Список журнала, четыре клиента одновременно:

[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 , я оставил только соответствующую часть, полный код здесь .

        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 .

Ответы [ 2 ]

4 голосов
/ 18 апреля 2012

Возможно, вы столкнулись с некоторой комбинацией задержки ACK и / или алгоритма Нейгла . Оба из них могут выборочно задерживать перемещение данных в сеансе TCP, и их реализации сильно различаются в зависимости от платформы.

Попробуйте использовать setsockopt() с TCP_NODELAY на сокете, чтобы отключить Nagle.

AFIK, Windows не позволяет отключить задержку ACK для каждого сокета: необходимо отредактировать реестр и отключить его для всех TCP. Поэтому сначала попробуйте TCP_NODELAY. Если это не работает, то поэкспериментируйте с отключением задержки ACK. Даже если редактирование реестра нецелесообразно для вашего приложения, знание того, является ли задержка ACK проблемой, может указать вам верное направление для других обходных путей.

1 голос
/ 10 апреля 2012

Я знаю, что это немного поздно, но, скорее всего, это из-за времени, которое требуется для настройки TCP-соединения между сервером и не инициирующим клиентом.

Идея заключается в том, что между клиентом-инициатором и сервером уже установлено TCP-соединение (оно устанавливается до сообщения первого клиента), поэтому в этом случае время, необходимое для выполнения трехстороннего рукопожатия, исключается.

Вы можете проверить это несколькими способами, наиболее простым из которых является установление соединения перед реальной обработкой сообщений (например, отправка фиктивного сообщения каждому из них).

Вы также можете переключиться на UDP, если не хотите устанавливать соединение с каждым клиентом, но тогда вы потеряете надежность TCP.

Я не уверен, что понял вашу заметку о Linux. Вы говорите, что он работает так, как задумано в Linux, но не в Windows? Если это так, нам нужно узнать больше о вашей настройке, например, все ли клиенты работают на одном хосте? В том же экземпляре браузера?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...