Poor network performance with Websockets running on apple device

I am working on an HTML/Javascript running on mobile devices that is communicating with a Qt/C++ application running on a PC. Both the mobile device and the PC are on a local network. The communication between the HTML page (client) and the C++ app (server) is done using Websockets.

The HTML page is a remote control for the C++ application, so it is needed to have a low latency connection between the mobile device and the PC.

When using any non-Apple device as a client, data is sent to a rate between 60 to 120 frames/sec, which is totally acceptable. When using an Apple device, this rate falls to 3-4 frames/sec. I also checked ping times (Websocket implementation, not a ping command from command line). They are acceptable (1-5 ms) for Apple devices as long as the device is not transmitting data. Whenever it transmits data, this ping time raises to 200ms.

Looking from the Javascript side, the Apple devices always send data at a consistent rate of 60 frames/sec, as any other devices do. However, on the server side, only 3 to 4 of these 60 frames are received when the client is an Apple device.

Does anyone have any idea on what can be happening?

Here is my Javascript code :

<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>

Data is sent from Javascript side using dosend() function.

Upvotes: 8

Views: 3412

Answers (2)

Kurt Pattyn
Kurt Pattyn

Reputation: 2788

The best way to get some more insight is to use the AutobahnTestsuite. You can test both clients and servers with that suite and find out where problems are situated.

I have created QWebSockets, a Qt based websockets implementation, and used that on several occasions to create servers. Performance from Apple devices is excellent.

However, there seems to be a severe problem with Safari when it comes to large messages (see https://github.com/KurtPattyn/QWebSockets/wiki/Performance-Tests). Maybe that is the problem.

Upvotes: 1

Tanner Sansbury
Tanner Sansbury

Reputation: 51871

Few ideas and suggestions.

  • Check if the client's WebSocket protocol is supported by the server. This question and answer discuss a case where different protocol versions were an issue.
  • The WebSocket standard permits implementations to arbitrarily delay transmissions and perform fragmentation. Additionally, control frames, such as Ping, do not support fragmentation, but are permitted to be interjected. These permitted behavioral difference may be contributing to the difference in times.
  • Check if the bufferedAmount attribute on the WebSocket to determine if the WebSocket is buffering the data. If the bufferedAmount attribute is often zero, then data has been passed to the OS, which may be buffering it based on OS or socket configurations, such as Nagle.
  • This question and answer mentions resolving delays by having the server send acknowledgements for each message.
  • To get a deeper view into the interactions, it may be useful to perform a packet trace. This technical Q&A in the Mac Developer Library may provide some resources as to how to accomplish this.

Upvotes: 1

Related Questions