Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   XMLSocket странное поведение (http://www.flasher.ru/forum/showthread.php?t=160514)

allah..beerbar 13.07.2011 17:16

XMLSocket странное поведение
 
Привет.
Есть проблема которую никак не получается понять.
Для наглядного понимания проблемы были написаны 2 простых приложения - клиент на AS3 и сервер на питоне, код которых выложен ниже.

Запускаем одновременно 2 клиента, располагаем их так, чтобы было видно оба окна, нажимаем connect и там и там.
После чего зажимаем в одном из клиентов любую кнопку.

Что должно происходить:
Клиент в котором зажата кнопка отправляет серверу сообщение “some data”, после чего сервер пересылаем его всем клиентам назад.
После чего каждый клиент двигает кнопку connectButton, и выводит сообщение в лог с временем минуты:секунды:милисекунды.

Что происходит не так:
В клиенте который отсылает сообщение движение происходит плавно, а во всех остальных клиентах движение дергается.
Это происходит потому, что сообщения до них доходят позже чем до клиента через который происходит отсылаемое сообщение.
Причем если запустить три клиента (назовем их A, B, C), и отсылать с A то время у B и C будет одинаково.

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

Хотя стоит сказать что винда плохая и на ubuntu linux 10.04 , Chrome 12.0 , flash player 10.3 все плавно, оба клиента запускаються в отдельных окнах хрома.

скрин винда
скрин линукс убунты

Листинг времени из сервака
Четыре клиента одновременно
[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
Код AS3:

package 
{
    import adobe.utils.CustomActions;
    import flash.display.Sprite;
    import flash.events.DataEvent;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.XMLSocket;
    import flash.system.Security;
    import flash.text.TextField;
 
    public class Main extends Sprite
    {
        private var socket          :XMLSocket;
        private var textField        :TextField = new TextField;
        private var connectButton    :TextField = new TextField;
 
        public function Main():void
        {
                if (stage) init();
                else addEventListener(Event.ADDED_TO_STAGE, init);
        }
 
 
 
        private function init(event:Event = null):void
        {
            socket = new XMLSocket();
            socket.addEventListener(Event.CONNECT, connectHandler);
            socket.addEventListener(DataEvent.DATA, dataHandler);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
 
            addChild(textField);
            textField.y = 50;
            textField.width = 780;
            textField.height = 500;
            textField.border = true;
 
            connectButton.selectable = false;
            connectButton.border = true;
            connectButton.addEventListener(MouseEvent.MOUSE_DOWN, connectMouseDownHandler);
            connectButton.width = 105;
            connectButton.height = 20;
            connectButton.text = "click here to connect";
            addChild(connectButton);
        }
 
 
 
        private function connectHandler(event:Event):void
        {
            textField.appendText("Connect\n");
            textField.appendText("Нажми и удерживай любую кнопку\n");
        }
 
 
 
        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 с пременением фреймворка twisted
Код:

from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory
from twisted.protocols.basic import LineOnlyReceiver
import datetime

class EchoProtocol(LineOnlyReceiver):
    #####
    name = ""
    id = 0
    delimiter = chr(0)
    #####
    def getName(self):
        return self.transport.getPeer().host

    def connectionMade(self):
        self.id = self.factory.getNextId()
        print "New connection from %s - id:%s" % (self.getName(), self.id)
        self.factory.clientProtocols[self.id] = self

    def connectionLost(self, reason):
        print "Lost connection from "+ self.getName()
        del self.factory.clientProtocols[self.id]
        self.factory.sendMessageToAllClients(self.getName() + " has disconnected.")

    def lineReceived(self, line):
        print "[%s] %s >> %s" % (datetime.datetime.now().time(), self, line)

        if line=="<policy-file-request/>":

            data = """<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<!-- Policy file for xmlsocket://ep1c.org -->
<cross-domain-policy>
    <allow-access-from domain="*" to-ports="%s" />
</cross-domain-policy>""" % PORT
            self.send(data)
        else:
            self.factory.sendMessageToAllClients( line )

    def send(self, line):
        print "[%s] %s << %s" % (datetime.datetime.now().time(), self, line)
        if line:
            self.transport.write( str(line) + chr(0))
        else:
            print "Nothing to send"


class ChatProtocolFactory(ServerFactory):
    protocol = EchoProtocol

    def __init__(self):
        self.clientProtocols = {}
        self.nextId = 0

    def getNextId(self):
        id = self.nextId
        self.nextId += 1
        return id

    def sendMessageToAllClients(self, msg):
        for client in self.clientProtocols:
            self.clientProtocols[client].send(msg)

    def sendMessageToClient(self, id, msg):
        self.clientProtocols[id].send(msg)

PORT = 1 # не настоящий
print "Starting Server"
factory = ChatProtocolFactory()
reactor.listenTCP(PORT, factory)
reactor.run()


wvxvw 13.07.2011 17:38

Возможно в Виндовс так многозадачность реализована, что окна в фоновом режиме обслуживаются "по возможности", а не "моментально"...

allah..beerbar 13.07.2011 17:56

Нет, все хуже :)
Если запустить все это с двух машин (A и B), в обоих окнах эти приложения будут не в фоновом, и с А слать мессаги, то в B все равно будет тот же негативный эффект.

alatar 13.07.2011 18:31

Вы не сможете гарантировать синхронность таким образом. Хотите синхронности — придется делать что-то типа этого: http://habrahabr.ru/blogs/gdev/123883/

allah..beerbar 13.07.2011 18:59

Да да, читал накануне.
Вопрос не в том как добиться синхронизации. Вопрос в том почему время настолько запаздывает? Если делать синхронизацию с учетом текущей задержки, то пинг подефолту будет начиная от 200. Даже по локальной сети! Да вы что, боже упаси!

alatar 13.07.2011 19:08

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

allah..beerbar 13.07.2011 22:09

Разница огромна. Дело в том, что если касяк как вы говорите в роутере сетевухе и прочем то с этим ничего не поделать. А если это касяк во флеше и его можно исправить то это нужно исправлять! Мне кажется это проблема всетаки решаемая силами флеш программиста. Ну посмотрите на симптомы, они очень странные.
Могу кое что добавить. Вот есть А, B, C клиента, шлем с A. на B и C мессаги доходят пачками примерно по штук 5ть в одно и тоже время.

Еще раз, вопрос не в том как добиться синхронности. Нет, это отдельный разговор. Вопрос в том - почему такая разница в пинге.

t4arty 13.07.2011 23:38

вообще смахивает на то, что просто забивается сеть => отсюда такие симптомы.

alatar 14.07.2011 01:44

Цитата:

на B и C мессаги доходят пачками примерно по штук 5ть в одно и тоже время.
Код:

self.transport.write( str(line) + chr(0))
В конце должен быть нулевой байт, а не символ с индексом 0.

allah..beerbar 14.07.2011 02:25

Цитата:

Сообщение от alatar (Сообщение 1011600)
Код:

self.transport.write( str(line) + chr(0))
В конце должен быть нулевой байт, а не символ с индексом 0.

Код:

>>> "\0" == chr(0)
True

учите мат часть ;)

allah..beerbar 31.10.2011 21:09

Проблему так и не решили ( может еще идеи есть у кого?

dimarik 31.10.2011 22:10

Вы же сами попросили подучить матчасть. Пока учим.


Часовой пояс GMT +4, время: 18:20.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.