Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QWebSocket::textMessageReceived() emitted after the socked is disconnected
Forum Updated to NodeBB v4.3 + New Features

QWebSocket::textMessageReceived() emitted after the socked is disconnected

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 637 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • AlveinA Offline
    AlveinA Offline
    Alvein
    wrote on last edited by Alvein
    #1

    Hello.

    I am connecting to a chat server through web sockets. Everything is nice, but when I close the connection, the QWebSocket signals keep arriving for some while, even if I forcefully delete the object.

    Why is this happening and how should I "cut" the communication instead?

    This is the class definition:

    class Chatbot:public QObject {
        Q_OBJECT
    public:
        Chatbot();
        ~Chatbot();
        bool         enterChat();
        void         leaveChat();
    private:
        QString      sChatURL;
        QWebSocket   *wsChat;
        CBChatStatus cbcsStatus;
    private slots:
        void on_connected();
        void on_disconnected();
        void on_textMessageReceived(QString);
    signals:
        void logEvent(QString);
    };
    

    And these are the methods, simplified for the sample:

    bool Chatbot::enterChat() {
        bool bEC=false;
        if(cbcsStatus==CBChatStatus::CBCS_DISCONNECTED) {
            emit logEvent(QStringLiteral("Connecting..."));
            wsChat=new QWebSocket;
            QObject::connect(wsChat,SIGNAL(connected()),this,SLOT(on_connected()));
            QObject::connect(wsChat,SIGNAL(disconnected()),this,SLOT(on_disconnected()));
            QObject::connect(wsChat,SIGNAL(textMessageReceived(QString)),this,SLOT(on_textMessageReceived(QString)));
            cbcsStatus=CBChatStatus::CBCS_CONNECTING; // EDIT
            wsChat->open(QUrl(sChatURL));
            bEC=true;
        }
        return bEC;
    }
    
    void Chatbot::leaveChat() {
        if(cbcsStatus!=CBChatStatus::CBCS_DISCONNECTED) {
            wsChat->close();
            wsChat->disconnect(); // EDIT
            delete wsChat;
            wsChat=nullptr;
        }
    }
    
    void Chatbot::on_connected() {
        emit logEvent(QStringLiteral("** Connected **"));
        cbcsStatus=CBChatStatus::CBCS_CONNECTED;
    }
    
    void Chatbot::on_disconnected() {
        emit logEvent(QStringLiteral("** Disconnected **"));
        cbcsStatus=CBChatStatus::CBCS_DISCONNECTED;
    }
    
    void Chatbot::on_textMessageReceived(QString sMessage) {
        emit logEvent(QStringLiteral("Message received: %1").arg(sMessage));
        // ...
    }
    

    *The logEvent() signal is just my way of registering events.

    So, after hitting some "End chat" button, which calls leaveChat(), I get the following in my log:

    ** Disconnected **
    Message received: <some server response>
    Message received: <some server response>
    Message received: <some server response>
    ...
    

    It seems that after some seconds, the server detects the connection is idle and finally closes it itself, but I should not be getting those messages in first place!

    Does anybody have an idea about what's happening?

    Thanks.

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      I would guess there is a second socket around otherwise I don't see why you would get the disconnected() debug output at all since you already disconnected the signals/slots. Simply inrt out the pointer of wsChat / sender() in the approriate functions.

      Also don't use disconnect(wsChat) but wsChat->disconnect(this) since you for sure won't disconnect all (also internal) signals wsChat is emitting.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      AlveinA 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        I would guess there is a second socket around otherwise I don't see why you would get the disconnected() debug output at all since you already disconnected the signals/slots. Simply inrt out the pointer of wsChat / sender() in the approriate functions.

        Also don't use disconnect(wsChat) but wsChat->disconnect(this) since you for sure won't disconnect all (also internal) signals wsChat is emitting.

        AlveinA Offline
        AlveinA Offline
        Alvein
        wrote on last edited by
        #3

        @Christian-Ehrlicher:

        I would guess there is a second socket around otherwise I don't see why you would get the disconnected() debug output at all since you already disconnected the signals/slots. Simply inrt out the pointer of wsChat / sender() in the approriate functions.

        I only use a single QWebSocket.

        And I close it right before QObject::disconnect().
        I have no idea if this close() method is synchronous, but it should be or if not, why is disconnected() being fired?

        I've logged wsChat in on_textMessageReceived() and it shows 0x0 !!

        And when the server finally closes the connection itself, on_disconnected() is triggered again, showing that wsChat is 0x0 as well.

        Just for testing, I've removed the wsChat=nullptr line inside leaveChat() (because it's worth nothing), and after that the debug line in on_textMessageReceived() crashes because wsChat is -1.

        That's insane.

        @Christian-Ehrlicher:

        Also don't use disconnect(wsChat) but wsChat->disconnect(this) since you for sure won't disconnect all (also internal) signals wsChat is emitting.

        Nothing else should fire my custom slot on_textMessageReceived() after disconnecting it.

        But I used wsChat->disconnect(this), and the result is the same.

        1 Reply Last reply
        0
        • nageshN Offline
          nageshN Offline
          nagesh
          wrote on last edited by
          #4

          @Alvein Just a suggestion
          In leaveChat() function call disconnectFromHost() which will trigger disconnected signal,
          In on_disconnected() slot perform cleanup task

          AlveinA 1 Reply Last reply
          0
          • nageshN nagesh

            @Alvein Just a suggestion
            In leaveChat() function call disconnectFromHost() which will trigger disconnected signal,
            In on_disconnected() slot perform cleanup task

            AlveinA Offline
            AlveinA Offline
            Alvein
            wrote on last edited by Alvein
            #5

            @nagesh

            There's no such thing as disconnectFromHost() in QWebSocket.

            Previously, I tried abort(), but the resulting behavior is the same.

            Deleting wsChat in on_disconnected() raises an exception in on_textMessageReceived(), because the textMessageReceived() signal keeps being triggered.

            ...

            At this point I don't care if the socket remains open forever. I just want to remove the wsChat object signal/slot connections inside leaveChat() or on_disconnected(). Seems like an impossible task, though.

            ...

            EDIT:

            Found the problem. The posted snippet was basically good. It's hard to tell in a few words but the CALLER was not having into account that cbcsStatus can take a little while going from CBChatStatus::CBCS_DISCONNECTED to CBChatStatus::CBCS_CONNECTED.

            A Chatbot instance is intended to be created multiple times, and the routine which does this decides if it's OK to invoke enterChat() according to the given instance status (CBCS_DISCONNECTED or not).

            So, enterChat() was being executed twice, even if a single bot was being used, overwriting the previous wsChat value. Boom.

            Solution? Just setting a new status, CBCS_CONNECTING, right before wsChat->open().

            Also, once wsChat is freed, there's no need of disconnecting signals/slots, BUT:

            I was wrong.

            This fails

            QObject::disconnect(wsChat);
            

            This works:

            wsChat->disconnect(this);
            // or
            QObject::disconnect(wsChat,nullptr,this,nullptr);
            

            This also works (a little more general:

            wsChat->disconnect();
            // or
            QObject::disconnect(wsChat,nullptr,nullptr,nullptr);
            

            I've done the modifications in the original snippet.

            Thanks to everyone for giving me ideas.

            1 Reply Last reply
            1

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved