Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-63719

Incoming QML WebSocket messages block main event loop against network

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: P2: Important P2: Important
    • 5.14.0
    • 5.9.1, 5.9.2, 5.10.0 Beta 1, 5.11.0
    • WebSockets
    • None
    • Linux yoga 4.12.8-2-ARCH #1 SMP PREEMPT Fri Aug 18 14:08:02 UTC 2017 x86_64 GNU/Linux

      macOS Sierra 10.12.6
    • b14f5f59a3ae96949e6a33302385a751d6448182

      To reproduce, try on different connection/ping speeds (trivial: cable, WiFi, 4G), and observe `delta: ` messages.

      Ideally (expected behaviour), there should be zero of those.

      Observed behavior is that incoming WebSocket messages block the main loop depending on the internet connection speed, which in this very testcase results in freezes for several seconds.

      I do not know of any QML-side workaround for this.

      I would expect reading from network to happen in a different thread from rendering by default, especially when there is no way to change that from QML.

      Testcase:

      import QtQuick 2.0
      import QtWebSockets 1.0
      
      Item {
        width: 360
        height: 360
      
        property url echoServer: 'ws://echo.websocket.org'
        property int concurrency: 5
        property int sizeStart: 1024 // 1 KiB
        property int sizeStop: 128 * 1024 // 128 KiB
      
        property int balance: 0
        property real lastTick: Date.now()
        property real startTime: Date.now()
        property int size: sizeStart
      
        WebSocket {
          id: socket
          url: echoServer
          active: true
          onTextMessageReceived: {
            log('Received message: ' + message.length)
            balance--
            var tick = Date.now()
            var delta = tick - lastTick
            if (delta > check.interval * 2)
              log('delta [missing]: ' + delta)
            if (balance === 0 && size > sizeStop)
              log('Total time: ' + (Date.now() - startTime) / 1000 + ' seconds')
          }
          onStatusChanged:
            if (socket.status == WebSocket.Error)
              log('Error: ' + socket.errorString)
            else if (socket.status == WebSocket.Open)
              log('Socket Opened')
            else if (socket.status == WebSocket.Closed)
              log('Socket closed')
        }
        Timer {
          id: check
          running: true
          interval: 10
          repeat: true
          onTriggered: {
            var tick = Date.now()
            var delta = tick - lastTick
            if (delta > interval * 2)
              log('delta: ' + delta)
            lastTick = tick
          }
        }
        Timer {
          running: socket.status === WebSocket.Open && balance == 0 && size <= sizeStop
          interval: 200
          repeat: true
          onTriggered: {
            for (var i = 0; i < concurrency; i++) {
              log('Sending message: ' + size)
              socket.sendTextMessage(new Array(size + 1).join('x'))
              balance++
            }
            size *= 2
          }
        }
        Text {
          id: messageBox
          anchors { bottom: parent.bottom; left: parent.left; right: parent.right }
        }
        function log(text) {
          console.log(text)
          messageBox.text += '\n' + text
        }
      }
      

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            kurt.pattyn Kurt Pattyn
            chalker Сковорода Никита
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes