【问题标题】:Poor network performance with Websockets running on apple device在苹果设备上运行 Websocket 时网络性能不佳
【发布时间】:2013-01-14 14:44:44
【问题描述】:

我正在开发一个在移动设备上运行的 HTML/Javascript,它与在 PC 上运行的 Qt/C++ 应用程序进行通信。移动设备和 PC 都在本地网络上。 HTML 页面(客户端)和 C++ 应用程序(服务器)之间的通信是使用 Websockets 完成的。

HTML 页面是 C++ 应用程序的远程控制,因此需要在移动设备和 PC 之间建立低延迟连接。

当使用任何非 Apple 设备作为客户端时,数据以 60 到 120 帧/秒之间的速率发送,这是完全可以接受的。使用 Apple 设备时,此速率降至 3-4 帧/秒。 我还检查了 ping 时间(Websocket 实现,而不是命令行中的 ping 命令)。只要设备不传输数据,它们对于 Apple 设备都是可以接受的(1-5 毫秒)。每当它传输数据时,这个 ping 时间都会增加到 200 毫秒。

从 Javascript 方面来看,Apple 设备始终以 60 帧/秒的一致速率发送数据,与任何其他设备一样。但是,在服务器端,当客户端是 Apple 设备时,这 60 个帧中仅接收到 3 到 4 个。

有人知道会发生什么吗?

这是我的 Javascript 代码:

<script language="javascript" type="text/javascript">

        var wsUri = document.URL.replace("http", "ws");
        var output;
        var websocket;


        function init()
        {
            output = document.getElementById("output");
            wsConnect();
        }

        function wsConnect()
        {
            console.log("Trying connection to " + wsUri);
            try
            {
                output = document.getElementById("output");
                websocket = new WebSocket(wsUri);
                websocket.onopen = function(evt)
                {
                        onOpen(evt)
                };
                websocket.onclose = function(evt)
                {
                        onClose(evt)
                };
                websocket.onmessage = function(evt)
                {
                        onMessage(evt)
                };
                websocket.onerror = function(evt)
                {
                        onError(evt)
                };
            }
            catch (e)
            {
                console.log("Exception " + e.toString());
            }
        }


        function onOpen(evt)
        {
            alert("Connected to " + wsUri);
        }

        function onClose(evt)
        {
            alert("Disconnected");
        }

        function onMessage(evt)
        {
            alert('Received message : ' + evt.data);
        }

        function onError(evt)
        {
            alert("Error : " + evt.toString());
        }

        function doSend(message)
        {
            websocket.send(message);
        }

        window.addEventListener("load", init, false);
</script>

使用 dosend() 函数从 Javascript 端发送数据。

【问题讨论】:

  • 您是否使用任何库来创建 websocket?
  • 不,我使用的是直接的 Javascript。在服务器端,我使用 boost asio 来处理连接和数据传输。这是(部分)我的 Javascript 代码:
  • 我编辑了最初的问题以包含我的 Javascript 代码。

标签: javascript c++ websocket boost-asio


【解决方案1】:

一些想法和建议。

  • 检查客户端的WebSocket协议是否被服务器支持。 This question and answer 讨论了不同协议版本存在问题的案例。
  • WebSocket standard 允许实现任意延迟传输并执行分段。此外,Ping 等控制帧不支持分段,但允许插入。这些允许的行为差异可能会导致时间差异。
  • 检查WebSocket 上的bufferedAmount 属性是否确定WebSocket 是否正在缓冲数据。如果bufferedAmount 属性通常为零,则数据已传递到操作系统,操作系统可能正在根据操作系统或套接字配置(例如Nagle)对其进行缓冲。
  • This question and answer 提到通过让服务器为每条消息发送确认来解决延迟问题。
  • 要更深入地了解交互,执行数据包跟踪可能很有用。 This Mac 开发人员库中的技术问答可能会提供一些有关如何完成此任务的资源。

【讨论】:

  • 感谢您的建议。 1.关于Websocket协议版本,我的服务器只支持最后一个版本(13),放弃了任何与旧版本连接的尝试。我再次检查了 iPad 是使用协议版本 13 连接的,所以问题不是来自这里。 2. 我收到的所有帧都没有表明它已被分段(FIN 位始终设置)。 3.我在哪里检查这个属性?这里没有关于握手的这样的属性。 4. 有趣。我已经在使用 TCP_NODELAY 所以这不是我的情况。除此之外,我还在数数据包,而丢失的数据包根本就不会到达。
  • 我会看一下 MacOs 数据包跟踪文档。我也在测试在 Mac 上运行我的服务器,看看 iPad+Mac 是否工作得更好......
  • 我刚刚检查了你所说的选项。所有这些都需要一台外部计算机来捕获来自 iPad 的数据包。我尝试了 Wireshard,我可以看到来自 iPad 的数据很少,就像我的应用程序一样。直接从 iPad 获取数据包会更有趣 - iPad 中似乎正在发生一些事情,它不允许大多数 Websocket 帧通过。我仍然遇到同样的问题,但感谢您抽出宝贵时间。
  • 我测试了在 Mac 上运行 C++ 应用程序。在这种情况下,iPad 表现良好(60 帧/秒)。但是在与 PC 通信时,它仍然会下降 3 帧/秒,与 Windows XP 或 Windows 7 无关。另一个想法?
【解决方案2】:

获得更多见解的最佳方法是使用AutobahnTestsuite。您可以使用该套件测试客户端和服务器,并找出问题所在。

我创建了QWebSockets,这是一个基于 Qt 的 websockets 实现,并多次使用它来创建服务器。 Apple 设备的性能非常出色。

但是,Safari 似乎在处理大型消息时存在严重问题(请参阅https://github.com/KurtPattyn/QWebSockets/wiki/Performance-Tests)。也许这就是问题所在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 1970-01-01
    • 2021-11-30
    • 2020-01-06
    相关资源
    最近更新 更多