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

Incoming QML WebSocket messages block main event loop against network

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • 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

    Description

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

      Attachments

        Issue Links

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

          Activity

            People

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

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes