Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QWebSocket and Synchronous Response/Request Cycle



  • Hello,

    I am writing a wrapper around a QWebSocket interface, so that I can provide the application with a simple to use API for making REST like calls and receiving request synchronously. I am using a callback system in which stored callbacks get executed and removed from a queue once a signal is emitted, but I am having trouble implementing the public methods so that they block until the signal is emitted without also blocking the main UI thread.

    One such method is as follows:

    void ApHorizon::fetchFieldOptions(QString tName, Utility::ApCallback callback)
    {    
        ....
        // Some initialization
        ....
    
        m_messageQueue.append(payload);
        addCallback(tName, callback);
    
        emit messageQueueChanged(m_messageQueue);
    
        QEventLoop loop;
        auto handle = connect(this, &ApHorizon::serverMessageReceived, [tName, &loop](const QString type) {
            if (type == tName) loop.quit();
        });
        loop.exec();
        disconnect(handle);
    }
    

    That is, I want the method to block until a signal with a specific QString is received, and then continue after the fact, but at the same time without blocking the UI or other application functionality. I have tried moving the class instance to a separate thread but it seems the QEventLoop is working on the main thread no matter what thread I am in.

    A humble thanks if you can provide some insight.


  • Qt Champions 2019

    @ad7000 A synchronous API means a blocking API. If you call such an API from your main thread then it will block. If you don't want this then don't use synchronous APIs.



  • @jsulm Understood. I do want the API to be synchronous, but only within it's own thread, so that it can run in parallel with the main thread. This is what I am trying to figure out.


  • Qt Champions 2019

    @ad7000 Then use this in its own thread not in main thread.



  • @jsulm I have tried having a QThread member variable in the class and moving the class instance to this thread in the class constructor, something like

    MyClass::MyClass(QObject *parent) : QObject(parent) {
        moveToThread(&m_myClassThread);
        m_myClassThread.start();
    }
    

    I have done this for several of the classes that use the API class, as well as on the API class itself, but the UI still blocks. Any suggestions?


  • Qt Champions 2019

    @ad7000 My suggestion would be to post more code, else it is hard to say why your UI is blocking...



  • @jsulm It's alright. I ended up going completely asynchronous by using a chained callback structure. Thanks anyways for the help!