【问题标题】:Strange Flash AS3 xml Socket behavior奇怪的 Flash AS3 xml 套接字行为
【发布时间】:2012-04-18 09:05:00
【问题描述】:

我有一个我无法理解的问题。

为了理解它,我在 AS3 上编写了一个套接字客户端,在 python/twisted 上编写了一个服务器,您可以在下面看到这两个应用程序的代码。

让我们同时启动两个clients,排列它们以便您可以看到两个窗口并在两个窗口中按下连接按钮。然后按住任意按钮。

我的期望:

按下按钮的客户端向服务器发送“一些数据”消息,然后服务器将此消息发送给所有客户端(包括原始发送者)。

然后每个客户端向右移动按钮“connectButton”并以以下格式将消息打印到日志中:“min:secs:milliseconds”。

出了什么问题:

在发送消息的客户端中,动作是平稳的,但在所有其他客户端中,动作是不稳定的。

发生这种情况是因为发送到这些客户端的消息比发送到原始发送客户端的消息晚。如果我们有三个客户端(我们命名为 A,B,C),我们从 A 发送一条消息,B 和 C 的发送时间日志将是相同的。

为什么其他客户端比原始发件人晚收到此消息?

顺便说一句,在 ubuntu 10.04/chrome 上,所有的动作都很流畅。两个客户端以分开的 chrome 启动。

windows screenshot

linux screenshot

日志列表,四个客户端同时:

[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 客户端代码,我只留下了相关部分,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.

【问题讨论】:

  • 这里只是一个想法,但我的印象是,如果 SWF 对象在 HTML 中没有焦点,它将以较低的帧速率运行。这可以解释“断断续续”,但是在 ubuntu/chrome 上它运行良好,这可能是该设置上的 flash 播放器处理它的方式不同。您是否在不同的机器上尝试过,而不仅仅是在同一台机器上?我依稀记得读到速度可以大幅下降到 2 FPS 左右
  • 谢谢,我用 ubuntu 试了 2 台不同的机器,用 widnows 试了 4 台,都一样。当我在两台不同的机器上运行两个客户端时(所有客户端都有一个焦点),客户端如何等待数据有不稳定的运动和糟糕的时间日志(就像我在下面发布的问题一样)。

标签: actionscript-3 flash networking


【解决方案1】:

您可能会遇到ACK delay 和/或Nagle's algorithm 的某种组合。这两者都可以选择性地延迟 TCP 会话上的数据移动,并且它们的实现因平台而异。

尝试在套接字上使用setsockopt()TCP_NODELAY 来禁用Nagle。

AFIK,Windows 不允许您基于每个套接字禁用 ACK 延迟:您必须 edit the registry 并为所有 TCP 禁用它。所以先试试TCP_NODELAY。如果这不起作用,则尝试禁用 ACK 延迟。即使注册表编辑对您的应用程序不实用,只要知道 ACK 延迟是否是问题所在,就可以为您指明其他解决方法的正确方向。

【讨论】:

  • 天啊,好像行得通!我在 twissted 服务器上的 connectionMade 方法中设置了self.transport.setTcpNoDelay(True)
【解决方案2】:

我知道这有点晚了,但这很可能是因为在服务器和非启动客户端之间建立 TCP 连接需要时间。

这个想法是在发起客户端和服务器之间已经建立了一个 TCP 连接(它在第一个客户端的消息之前建立),因此在这种情况下消除了进行 3 次握手所花费的时间。

您可以通过几种方式对此进行测试,最简单的方法是在您真正处理消息之前建立连接(例如,通过向每个消息发送虚拟消息)。

如果您不想与每个客户端都建立连接,也可以切换到 UDP,但这样会失去 TCP 的可靠性。

我不确定我是否理解您关于 Linux 的说明。你是说它在 Linux 上按预期工作,但在 Windows 上不工作?如果是这样,我们需要更多地了解您的设置,例如所有客户端是否都在同一主机上运行?在同一个浏览器实例中?

【讨论】:

  • 还不晚,谢谢。数据发送前已建立连接。我可以通过打开两个客户端(问题开头的链接)并与他们一起玩来检查它。是的,它按照我在 linux 上的意图工作。与客户端相同的主机,相同的 Flash 播放器,两者都有 chrome。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
相关资源
最近更新 更多