Results 1 to 6 of 6

Thread: QWebChannel - QWebSocket - threading problem

  1. #1
    Join Date
    May 2013
    Location
    Bialystok/Poland
    Posts
    13
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default QWebChannel - QWebSocket - threading problem

    Hi,
    I am using QWebChannel to expose easy communication interface to connected web browser clients.

    Also I have overridden QWebChannelAbstractTransport interface which sends and receives data from/to QWebSocket.

    When my client connects and all of the code runs in event loop of main thread all works great,
    but when specific action occurs in the application I need to create new thread and move all of the client resources to this thread.
    I have properly implemented parent->child hierarchy for moveToThread() operation.

    When moveToThread() operation completes successfully and all object runs in new event loop (<- I think) clients can easily send me a message and I can easily process it in new thread,
    but when my application trying to send message to client I am receiving console message error: "QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread".

    I tried to debug it by printing threads in which objects or called methods works and it seems that everything is fine, but doesn't work.


    TESTCASE
    Part of my QWebChannelAbstractTransport implementation:

    Output from qDebug line 11 looks like this: "Client in msg from thread >>> QThread(0x6aa270)"
    Output from qDebug line 3 looks like this: "Client out msg from thread <<< QThread(0x6aa270) (socket: QThread(0x6aa270) )"
    So it looks like all of object runs in the same thread but in line 6 I have a message: "QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread"
    Of course socket is QWebSocket object.

    Qt Code:
    1. void ClientTransportLayer::sendMessage(const QJsonObject &message)
    2. {
    3. qDebug() <<"Client out msg from thread <<< " <<QThread::currentThread() <<" (socket: " <<socket->thread() <<")";
    4.  
    5. QJsonDocument doc(message);
    6. socket->sendTextMessage(QString::fromUtf8(doc.toJson(QJsonDocument::Compact)));
    7. }
    8.  
    9. void ClientTransportLayer::textMessageReceived(const QString &messageData)
    10. {
    11. qDebug() <<"Client in msg from thread >>> " <<QThread::currentThread();
    12.  
    13. QJsonParseError error;
    14. QJsonDocument message = QJsonDocument::fromJson(messageData.toUtf8(), &error);
    15.  
    16. if(!error.error && message.isObject())
    17. emit messageReceived(message.object(), this);
    18. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,546 Times in 1,496 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QWebChannel - QWebSocket - threading problem

    Can you show how the application uses this to send messages?
    Does this happen from the main thread? Via signal/slot?

    One thing you could try debugging-wise is to find the socket notifier message in Qt, set a break point there and then see which thread causes it.

    Cheers,
    _

  3. #3
    Join Date
    May 2013
    Location
    Bialystok/Poland
    Posts
    13
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QWebChannel - QWebSocket - threading problem

    Thank you for your interest.

    sendMessage is overridden [pure virtual slot] of QWebChannelAbstractTransport
    I am using this with QWebChannel so sendMessage is called by QWebChannel mechanism
    for example as an automatic confirmation response for method called remotely from client side.
    When I need to manually (from my code) send message to client, I simply emit a signal from my object registered for publish in QWebChannel object.


    My textMessageReceived is connected to QWebSocket that way in constructor
    Qt Code:
    1. connect(this->socket, SIGNAL(textMessageReceived(QString)), this, SLOT(textMessageReceived(QString)));
    To copy to clipboard, switch view to plain text mode 


    That is simplified backtrace for thread running my objects in case of my first example above
    Qt Code:
    1. Thread 4 (Thread 0x7fffe73ba700 (LWP 23225)):
    2. #0 ClientTransportLayer::sendMessage (this=0x7fffd8002f90, message=...) at ./src/clienttransportlayer.cpp:22
    3. __PRETTY_FUNCTION__ = "virtual void ClientTransportLayer::sendMessage(const QJsonObject&)"
    4. doc = {static BinaryFormatTag = 1936351857, d = 0x40ece8 <ClientTransportLayer::sendMessage(QJsonObject const&)>}
    5. #1 0x00007ffff6fc7bb6 in QMetaObjectPublisher::handleMessage (this=0x7fffd8002fd0, message=..., transport=0x7fffd8002f90) at /home/rafal/Dokumenty/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp:641
    6. __PRETTY_FUNCTION__ = "void QMetaObjectPublisher::handleMessage(const QJsonObject&, QWebChannelAbstractTransport*)"
    7. type = TypeInit
    8. #2 0x00007ffff6fc253a in QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<QJsonObject const&, QWebChannelAbstractTransport*>, void, void (QMetaObjectPublisher::*)(QJsonObject const&, QWebChannelAbstractTransport*)>::call (f=(void (QMetaObjectPublisher::*)(QMetaObjectPublisher * const, const QJsonObject &, QWebChannelAbstractTransport *)) 0x7ffff6fc7852 <QMetaObjectPublisher::handleMessage(QJsonObject const&, QWebChannelAbstractTransport*)>, o=0x7fffd8002fd0, arg=0x7fffe73b9700) at /home/rafal/Qt/5.7/gcc_64/include/QtCore/qobjectdefs_impl.h:507
    9. #3 0x00007ffff6fc2388 in QtPrivate::FunctionPointer<void (QMetaObjectPublisher::*)(QJsonObject const&, QWebChannelAbstractTransport*)>::call<QtPrivate::List<QJsonObject const&, QWebChannelAbstractTransport*>, void> (f=(void (QMetaObjectPublisher::*)(QMetaObjectPublisher * const, const QJsonObject &, QWebChannelAbstractTransport *)) 0x7ffff6fc7852 <QMetaObjectPublisher::handleMessage(QJsonObject const&, QWebChannelAbstractTransport*)>, o=0x7fffd8002fd0, arg=0x7fffe73b9700) at /home/rafal/Qt/5.7/gcc_64/include/QtCore/qobjectdefs_impl.h:526
    10. #4 0x00007ffff6fc1ea0 in QtPrivate::QSlotObject<void (QMetaObjectPublisher::*)(QJsonObject const&, QWebChannelAbstractTransport*), QtPrivate::List<QJsonObject const&, QWebChannelAbstractTransport*>, void>::impl (which=1, this_=0x7fffd8004640, r=0x7fffd8002fd0, a=0x7fffe73b9700, ret=0x0) at /home/rafal/Qt/5.7/gcc_64/include/QtCore/qobject_impl.h:149
    11. #5 0x00007ffff67d677d in QMetaObject::activate(QObject*, int, int, void**) () from /home/rafal/Qt/5.7/gcc_64/lib/libQt5Core.so.5
    12. #6 0x00007ffff6fd7478 in QWebChannelAbstractTransport::messageReceived (this=0x7fffd8002f90, _t1=..., _t2=0x7fffd8002f90) at .moc/moc_qwebchannelabstracttransport.cpp:150
    13. _a = {0x0, 0x7fffe73b9770, 0x7fffe73b96e8}
    14. #7 0x000000000040f0bb in ClientTransportLayer::textMessageReceived (this=0x7fffd8002f90, messageData=...) at ./src/clienttransportlayer.cpp:37
    15. __PRETTY_FUNCTION__ = "void ClientTransportLayer::textMessageReceived(const QString&)"
    16. error = {offset = 0, error = QJsonParseError::NoError}
    17. message = {static BinaryFormatTag = 1936351857, d = 0x7fffd8004220}
    18. #8 0x000000000041a2bb in ClientTransportLayer::qt_static_metacall (_o=0x7fffd8002f90, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7fffe73b9910) at moc_clienttransportlayer.cpp:71
    19. #9 0x00007ffff67d6056 in QMetaObject::activate(QObject*, int, int, void**) () from /home/rafal/Qt/5.7/gcc_64/lib/libQt5Core.so.5
    20. #10 0x00007ffff7204f65 in QWebSocket::textMessageReceived(QString const&) () from /home/rafal/Qt/5.7/gcc_64/lib/libQt5WebSockets.so.5
    21. #11 0x00007ffff67d677d in QMetaObject::activate(QObject*, int, int, void**) () from /home/rafal/Qt/5.7/gcc_64/lib/libQt5Core.so.5
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,546 Times in 1,496 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QWebChannel - QWebSocket - threading problem

    Quote Originally Posted by RafalNiewinski View Post
    I am using this with QWebChannel so sendMessage is called by QWebChannel mechanism
    And the QWebChannel has also been moved to the

    Quote Originally Posted by RafalNiewinski View Post
    When I need to manually (from my code) send message to client, I simply emit a signal from my object registered for publish in QWebChannel object.


    My textMessageReceived is connected to QWebSocket that way in constructor
    Qt Code:
    1. connect(this->socket, SIGNAL(textMessageReceived(QString)), this, SLOT(textMessageReceived(QString)));
    To copy to clipboard, switch view to plain text mode 
    That looks ok, the cross thread signal/slot connection handling should have transported the call into the thread of "this".

    Cheers,
    _

  5. #5
    Join Date
    May 2013
    Location
    Bialystok/Poland
    Posts
    13
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QWebChannel - QWebSocket - threading problem

    Yes of course, all objects was moved to the same (new) thread.
    I checked that by calling this on each object and all resides in same thread.
    Qt Code:
    1. qDebug() <<x.thread();
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,546 Times in 1,496 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QWebChannel - QWebSocket - threading problem

    Right, then the best choice is likely to see where the call is coming from that triggers the warning.

    Cheers,
    _

Similar Threads

  1. Replies: 3
    Last Post: 18th May 2016, 06:47
  2. Need help handling received messages with QWebSocket based GUI
    By JaffaMicrobrain in forum Qt Programming
    Replies: 5
    Last Post: 26th August 2015, 16:22
  3. Where is qwebchannel.js?
    By RolandHughes in forum Qt Programming
    Replies: 1
    Last Post: 7th June 2015, 10:42
  4. Static class threading problem
    By WSQtProgrammer in forum Qt Programming
    Replies: 1
    Last Post: 3rd August 2012, 21:42
  5. Qt Multi Threading RePainting Problem
    By Mohammad in forum Qt Programming
    Replies: 4
    Last Post: 12th January 2012, 15:52

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.