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. MQTT Connection Problem
QtWS25 Last Chance

MQTT Connection Problem

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 6 Posters 876 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.
  • U unamlositp
    10 Sept 2024, 20:34

    Hello everybody, I need some help with QtMqtt library.

    I'm trying to code a program that takes in input hostname, port and topic and starts publishing messages in that topic.

    The problem I am encountering is that once i try to connect with "m_client->connectToHost" it doesn't connect at all, and stays in "Connecting" state.

    Do anybody have some advices?

    This is my function:

    #include "client.h"
    #include <QDebug>
    #include <QMqttTopicName>
    #include <iostream>
    #include <QObject>
    
    
    Client::Client(QObject *parent)
        : QObject{parent}
    {}
    
    void makeConnection();
    
    
    void Client::setup(){
    
        qint16 port;
        m_client = new QMqttClient(this);
    
    
        std::cout << "Inserisci l'hostname: ";
        QTextStream host(stdin);
        QString phrase1 = host.readLine();
        m_client->setHostname(phrase1);
        qDebug() << "l'hostname settato è: "<<m_client->hostname();
    
        std::cout << "Inserisci la porta: ";
        std::cin >> port;
        std::cin.ignore();
        m_client->setPort(port);
        qDebug() << "la porta settata è: "<<m_client->port();
    
        makeConnection();
    
        qDebug() << "porta e host settati.";
        qDebug() << m_client->state();
    
        std::cout << "Inserisci il topic: ";
        QTextStream tpc(stdin);
        const QString &indirizzoTpc = tpc.readLine();
    
        while(true){
            std::cout << "inserisci il messaggio da mandare: ";
    
            QTextStream msg(stdin);
            const auto &message = msg.readLine();
    
            if(message == "termine")
                break;
    
            m_client->publish(QMqttTopicName(indirizzoTpc), message.toUtf8());
    
            qDebug() << "messaggio inviato nel topic:\n" << indirizzoTpc;
        }
    
        exit(0);
    }
    
    void Client::makeConnection(){
        m_client->connectToHost();
        std::cout << "Client in connessione...\n";
    }
    
    

    Along with the header:

    #ifndef CLIENT_H
    #define CLIENT_H
    
    #include <QObject>
    #include <QtMqtt/QMqttClient>
    
    
    class Client : public QObject
    {
        Q_OBJECT
    public:
        explicit Client(QObject *parent = nullptr);
        void setup();
        QMqttClient *m_client;
        void makeConnection();
    
    
    signals:
        void connessione_effettuata();
    
    public slots:
    };
    
    #endif // CLIENT_H
    
    
    P Offline
    P Offline
    Pl45m4
    wrote on 11 Sept 2024, 02:36 last edited by Pl45m4 9 Nov 2024, 02:37
    #3

    @unamlositp said in MQTT Connection Problem:

    i try to connect with "m_client->connectToHost" it doesn't connect at all, and stays in "Connecting" state.

    @unamlositp said in MQTT Connection Problem:

    while(true ) {
        std::cout << "inserisci il messaggio da mandare: ";
    
        QTextStream msg(stdin);
        const auto &message = msg.readLine();
    
        if(message == "termine")
            break;
    
        m_client->publish(QMqttTopicName(indirizzoTpc), message.toUtf8());
    
        qDebug() << "messaggio inviato nel topic:\n" << indirizzoTpc;
    }
    
    exit(0);
    

    I wonder why 🤔

    while(true) without any multithreading is the worst thing you can do in an event based framework like Qt.
    Your code stops the Qt internal event loop from working, so no events or signals (that, for example, a state has changed) are transmitted.
    And don't even think about adding a thread to your app - you don't need it, since QMQTT works just fine using Qt Signals and async functions.

    Do anybody have some advices?

    It seems like you are lacking a lot C++ knowledge.
    Get familiar with C++ basics, learn the principles of Qt (Signals & Slots, Qt Event System, Meta Object, QObject Tree) and then come back to your app.
    You don't have to, but it helps a lot and you will make fewer “rookie mistakes”, like using while loops in the wrong places and therefore completely blocking your app.

    void makeConnection();
    

    What is this free-floating function call/definition above void Client::setup() in your client.cpp?

    exit(0);
    

    What is this? What are you expecting from this inside a member function?


    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

    ~E. W. Dijkstra

    U 1 Reply Last reply 11 Sept 2024, 14:02
    3
    • J JKSH
      11 Sept 2024, 02:24

      Hello @unamlositp, and welcome!

      For a quick sanity check, please run the official Simple MQTT Client example: https://doc.qt.io/qt-6/qtmqtt-simpleclient-example.html Does this work for you?

      U Offline
      U Offline
      unamlositp
      wrote on 11 Sept 2024, 09:03 last edited by
      #4

      @JKSH Hello, thanks for replying. I tried it before starting my personal one, and it does work

      J 1 Reply Last reply 11 Sept 2024, 12:25
      0
      • V VRonin referenced this topic on 11 Sept 2024, 09:36
      • U unamlositp
        11 Sept 2024, 09:03

        @JKSH Hello, thanks for replying. I tried it before starting my personal one, and it does work

        J Offline
        J Offline
        JKSH
        Moderators
        wrote on 11 Sept 2024, 12:25 last edited by
        #5

        @unamlositp said in MQTT Connection Problem:

        @JKSH Hello, thanks for replying. I tried it before starting my personal one, and it does work

        Then I recommend you study the code in that example and adapt it for your own project.

        @Pl45m4 has correctly identified that your infinite while() loop blocks your event loop, and this prevents your connection from proceeding.

        After you call m_client->connectToHost(); all of your functions must return so that the event loop can process the connection. Don't try to do anything else until the connected() signal is emitted: https://doc.qt.io/qt-6/qmqttclient.html#connected

        P.S. You should familiarize yourself with Qt's signals and slots first

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        1 Reply Last reply
        5
        • P Pl45m4
          11 Sept 2024, 02:36

          @unamlositp said in MQTT Connection Problem:

          i try to connect with "m_client->connectToHost" it doesn't connect at all, and stays in "Connecting" state.

          @unamlositp said in MQTT Connection Problem:

          while(true ) {
              std::cout << "inserisci il messaggio da mandare: ";
          
              QTextStream msg(stdin);
              const auto &message = msg.readLine();
          
              if(message == "termine")
                  break;
          
              m_client->publish(QMqttTopicName(indirizzoTpc), message.toUtf8());
          
              qDebug() << "messaggio inviato nel topic:\n" << indirizzoTpc;
          }
          
          exit(0);
          

          I wonder why 🤔

          while(true) without any multithreading is the worst thing you can do in an event based framework like Qt.
          Your code stops the Qt internal event loop from working, so no events or signals (that, for example, a state has changed) are transmitted.
          And don't even think about adding a thread to your app - you don't need it, since QMQTT works just fine using Qt Signals and async functions.

          Do anybody have some advices?

          It seems like you are lacking a lot C++ knowledge.
          Get familiar with C++ basics, learn the principles of Qt (Signals & Slots, Qt Event System, Meta Object, QObject Tree) and then come back to your app.
          You don't have to, but it helps a lot and you will make fewer “rookie mistakes”, like using while loops in the wrong places and therefore completely blocking your app.

          void makeConnection();
          

          What is this free-floating function call/definition above void Client::setup() in your client.cpp?

          exit(0);
          

          What is this? What are you expecting from this inside a member function?

          U Offline
          U Offline
          unamlositp
          wrote on 11 Sept 2024, 14:02 last edited by
          #6

          @Pl45m4 Hi, thanks for answering my question.

          You're actually right, this is my first time dealing with C++ and Qt, i'm still trying to figure out the correct way to improve my code.
          Thanks for the advices, i'll for sure focus more on getting basic knowledge of the language and the framework.

          @Pl45m4 said in MQTT Connection Problem:

          What is this? What are you expecting from this inside a member function?

          I used that instruction to completely end the program when i typed the keyword "termine", maybe i should put it in main function.

          @Pl45m4 said in MQTT Connection Problem:

          while(true) without any multithreading is the worst thing you can do in an event based framework like Qt.
          Your code stops the Qt internal event loop from working, so no events or signals (that, for example, a state has changed) are transmitted.
          And don't even think about adding a thread to your app - you don't need it, since QMQTT works just fine using Qt Signals and async functions.

          Thanks for the feedback, I'll try to make it better by using Signals and Slots, never thought about "blocking" my code with that function.

          Sorry for replying so late, but i'm limited to 1 answer each hour :(

          A 1 Reply Last reply 11 Sept 2024, 14:48
          1
          • U unamlositp
            11 Sept 2024, 14:02

            @Pl45m4 Hi, thanks for answering my question.

            You're actually right, this is my first time dealing with C++ and Qt, i'm still trying to figure out the correct way to improve my code.
            Thanks for the advices, i'll for sure focus more on getting basic knowledge of the language and the framework.

            @Pl45m4 said in MQTT Connection Problem:

            What is this? What are you expecting from this inside a member function?

            I used that instruction to completely end the program when i typed the keyword "termine", maybe i should put it in main function.

            @Pl45m4 said in MQTT Connection Problem:

            while(true) without any multithreading is the worst thing you can do in an event based framework like Qt.
            Your code stops the Qt internal event loop from working, so no events or signals (that, for example, a state has changed) are transmitted.
            And don't even think about adding a thread to your app - you don't need it, since QMQTT works just fine using Qt Signals and async functions.

            Thanks for the feedback, I'll try to make it better by using Signals and Slots, never thought about "blocking" my code with that function.

            Sorry for replying so late, but i'm limited to 1 answer each hour :(

            A Offline
            A Offline
            artwaw
            wrote on 11 Sept 2024, 14:48 last edited by
            #7

            @unamlositp said in MQTT Connection Problem:

            I used that instruction to completely end the program when i typed the keyword "termine", maybe i should put it in main function.

            You should send a signal connected to appropriate slot in your QCoreApplication/QGuiApplication to properly exit the program. Not much of a problem in a simple program but an opportunity to imprint the right habits.

            For more information please re-read.

            Kind Regards,
            Artur

            U 1 Reply Last reply 11 Sept 2024, 16:18
            4
            • A artwaw
              11 Sept 2024, 14:48

              @unamlositp said in MQTT Connection Problem:

              I used that instruction to completely end the program when i typed the keyword "termine", maybe i should put it in main function.

              You should send a signal connected to appropriate slot in your QCoreApplication/QGuiApplication to properly exit the program. Not much of a problem in a simple program but an opportunity to imprint the right habits.

              U Offline
              U Offline
              unamlositp
              wrote on 11 Sept 2024, 16:18 last edited by
              #8

              @Pl45m4 As you adviced me I tried removing the loops, and using signals instead.

              I also created some classes, one for each feature I want my program to have, but I still can't get it right.

              I read on documentation that "QMqttClient::connected()" is a signal sent when the client is successfully connected to the host, but there's still something i'm missing, because I still can't use it correctly. When i try to use it in a "connect" function, it gives me back the error you can see in the image below:
              1d04b042-90e2-49a5-abd5-46638a6743d8-image.png

              I tried my own implementation, but still not success at all. These are my functions now:

              https://drive.google.com/file/d/1GamXYJo1XufG94AD24Xa1UOF2zJ1XkBz/view?usp=sharing

              (I know it's a gDrive file, but if i paste code here it gets flagged as spam, I don't know why, forgive me for this)

              I know I'm missing something, but I can't get to the point where i understand what's I'm actually doing bad.

              1 Reply Last reply
              0
              • V Offline
                V Offline
                VRonin
                wrote on 11 Sept 2024, 16:32 last edited by
                #9

                client is not a QMqttClient subclass, it's a QObject suclass so it doesn't have the connected signal.

                Also, Client::MakeConnection() still shows you didn't grasp the async nature of the class yet. you can't call a method to connect/write and rely on the operation being completed on the next instruction, the operation will be scheduled and done later, you should wait for the corresponding signal.

                P.S.
                pastebin.com for short snippets of code
                github.com for multi-file code sharing

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                P 1 Reply Last reply 11 Sept 2024, 16:53
                2
                • V VRonin
                  11 Sept 2024, 16:32

                  client is not a QMqttClient subclass, it's a QObject suclass so it doesn't have the connected signal.

                  Also, Client::MakeConnection() still shows you didn't grasp the async nature of the class yet. you can't call a method to connect/write and rely on the operation being completed on the next instruction, the operation will be scheduled and done later, you should wait for the corresponding signal.

                  P.S.
                  pastebin.com for short snippets of code
                  github.com for multi-file code sharing

                  P Offline
                  P Offline
                  Pl45m4
                  wrote on 11 Sept 2024, 16:53 last edited by Pl45m4 9 Nov 2024, 16:58
                  #10

                  @unamlositp

                  I would connect the QMQTT things in Client class itself. There you have direct access to the object.
                  Your client then acts as wrapper for QMqttClient.
                  Only expose functions to "control" the client to the outside...
                  So in your main.cpp you go client.start() (or init() or Setup() or whatever you call it) and let the client handle the rest.

                  Something like:
                  (Within your Client Constructor)

                  Client::Client(QObject *parent)
                      : QObject{parent}
                  {
                     connect(m_client, &QMqttClient::connected, this, &Client::handleConnection);
                  }
                  

                  Add some slot or function to do what you want to do as soon as you are connected.

                  Look at the example again what @JKSH linked above. It might give you some inspiration what you can do.

                  @VRonin said in MQTT Connection Problem:

                  pastebin.com for short snippets of code

                  Or add it to </> Code Section directly in the post.


                  If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                  ~E. W. Dijkstra

                  U 1 Reply Last reply 11 Sept 2024, 19:52
                  2
                  • P Pl45m4
                    11 Sept 2024, 16:53

                    @unamlositp

                    I would connect the QMQTT things in Client class itself. There you have direct access to the object.
                    Your client then acts as wrapper for QMqttClient.
                    Only expose functions to "control" the client to the outside...
                    So in your main.cpp you go client.start() (or init() or Setup() or whatever you call it) and let the client handle the rest.

                    Something like:
                    (Within your Client Constructor)

                    Client::Client(QObject *parent)
                        : QObject{parent}
                    {
                       connect(m_client, &QMqttClient::connected, this, &Client::handleConnection);
                    }
                    

                    Add some slot or function to do what you want to do as soon as you are connected.

                    Look at the example again what @JKSH linked above. It might give you some inspiration what you can do.

                    @VRonin said in MQTT Connection Problem:

                    pastebin.com for short snippets of code

                    Or add it to </> Code Section directly in the post.

                    U Offline
                    U Offline
                    unamlositp
                    wrote on 11 Sept 2024, 19:52 last edited by unamlositp 9 Nov 2024, 19:59
                    #11

                    @Pl45m4 said in MQTT Connection Problem:

                    I would connect the QMQTT things in Client class itself. There you have direct access to the object.
                    Your client then acts as wrapper for QMqttClient.
                    Only expose functions to "control" the client to the outside...
                    So in your main.cpp you go client.start() (or init() or Setup() or whatever you call it) and let the client handle the rest.

                    Something like:
                    (Within your Client Constructor)

                    I tried this approach, but no success, the result is still the same: it gets locked here
                    f38e4051-31ea-45f8-a7b2-bf5406b8f55e-image.png

                    It seems like it gets stuck, even after calling that part of the function with a signal.

                    EDIT:
                    I added some lines before the m_client->connectToHost() one, just to know if the code actually gets there, and it does.

                    void Client::MakeConnection(){
                        qDebug()<< "la funzione è stata chiamata"
                                 << "\nl'host è ancora: "<< m_client->hostname()
                                 <<"\nla porta è ancora: "<< m_client->port();
                    
                        m_client->connectToHost();
                        if (m_client->state()==QMqttClient::Connected){
                            emit ConnessoConSuccesso();
                        }
                    }
                    

                    It just gets stuck:
                    a24c9910-f374-4831-b6bc-44cdc99b2bf3-image.png

                    J P 2 Replies Last reply 11 Sept 2024, 20:51
                    0
                    • U unamlositp
                      11 Sept 2024, 19:52

                      @Pl45m4 said in MQTT Connection Problem:

                      I would connect the QMQTT things in Client class itself. There you have direct access to the object.
                      Your client then acts as wrapper for QMqttClient.
                      Only expose functions to "control" the client to the outside...
                      So in your main.cpp you go client.start() (or init() or Setup() or whatever you call it) and let the client handle the rest.

                      Something like:
                      (Within your Client Constructor)

                      I tried this approach, but no success, the result is still the same: it gets locked here
                      f38e4051-31ea-45f8-a7b2-bf5406b8f55e-image.png

                      It seems like it gets stuck, even after calling that part of the function with a signal.

                      EDIT:
                      I added some lines before the m_client->connectToHost() one, just to know if the code actually gets there, and it does.

                      void Client::MakeConnection(){
                          qDebug()<< "la funzione è stata chiamata"
                                   << "\nl'host è ancora: "<< m_client->hostname()
                                   <<"\nla porta è ancora: "<< m_client->port();
                      
                          m_client->connectToHost();
                          if (m_client->state()==QMqttClient::Connected){
                              emit ConnessoConSuccesso();
                          }
                      }
                      

                      It just gets stuck:
                      a24c9910-f374-4831-b6bc-44cdc99b2bf3-image.png

                      J Offline
                      J Offline
                      JonB
                      wrote on 11 Sept 2024, 20:51 last edited by JonB 9 Nov 2024, 20:54
                      #12

                      @unamlositp said in MQTT Connection Problem:

                      m_client->connectToHost();
                      if (m_client->state()==QMqttClient::Connected){
                          emit ConnessoConSuccesso();
                      }
                      

                      I have never used MQTT and don't know what it is. But void QMqttClient::connectToHost() says:

                      Initiates a connection to the MQTT broker.

                      It initiates a connection but does not wait for completion. You need to attach a slot to void QMqttClient::connected() to know when connection completes. It's too early to test for QMqttClient::Connected on the following line.

                      Please read @VRonin's post above where he explained exactly this.

                      1 Reply Last reply
                      2
                      • U unamlositp
                        11 Sept 2024, 19:52

                        @Pl45m4 said in MQTT Connection Problem:

                        I would connect the QMQTT things in Client class itself. There you have direct access to the object.
                        Your client then acts as wrapper for QMqttClient.
                        Only expose functions to "control" the client to the outside...
                        So in your main.cpp you go client.start() (or init() or Setup() or whatever you call it) and let the client handle the rest.

                        Something like:
                        (Within your Client Constructor)

                        I tried this approach, but no success, the result is still the same: it gets locked here
                        f38e4051-31ea-45f8-a7b2-bf5406b8f55e-image.png

                        It seems like it gets stuck, even after calling that part of the function with a signal.

                        EDIT:
                        I added some lines before the m_client->connectToHost() one, just to know if the code actually gets there, and it does.

                        void Client::MakeConnection(){
                            qDebug()<< "la funzione è stata chiamata"
                                     << "\nl'host è ancora: "<< m_client->hostname()
                                     <<"\nla porta è ancora: "<< m_client->port();
                        
                            m_client->connectToHost();
                            if (m_client->state()==QMqttClient::Connected){
                                emit ConnessoConSuccesso();
                            }
                        }
                        

                        It just gets stuck:
                        a24c9910-f374-4831-b6bc-44cdc99b2bf3-image.png

                        P Offline
                        P Offline
                        Pl45m4
                        wrote on 12 Sept 2024, 02:51 last edited by Pl45m4 9 Dec 2024, 03:02
                        #13

                        @unamlositp said in MQTT Connection Problem:

                        It seems like it gets stuck, even after calling that part of the function with a signal.

                        It's still not used in a clean way.

                        Just look at the example program here:

                        • https://doc.qt.io/qt-6/qtmqtt-simpleclient-mainwindow-cpp.html

                        It has a GUI, but you can take the initialization part for your console program as well.

                        To check the connection and to play around with it, you don't need more than this:

                        client.h

                        #ifndef CLIENT_H
                        #define CLIENT_H
                        
                        #include <QObject>
                        #include <QtMqtt/QMqttClient>
                        
                        class Client : public QObject
                        {
                            Q_OBJECT
                        
                        public:
                        
                            explicit Client(QObject *parent = nullptr);
                            void setup();
                        
                        public slots:
                        
                             void onStateChanged();
                        
                        private:
                        
                            QMqttClient *m_client;
                        };
                        
                        #endif // CLIENT_H
                        

                        client.cpp

                        #include "client.h"
                        #include <iostream>
                        
                        Client::Client(QObject *parent)
                            : QObject{parent}
                        {
                            m_client = new QMqttClient(this);
                        
                            connect(m_client, &QMqttClient::stateChanged, this, &Client::onStateChanged);
                        
                            // setup();
                        }
                        
                        void Client::setup()
                        {
                             // hostname:
                             std::cout << "\ninserire l'hostname: ";
                             QTextStream host(stdin);
                             QString Shost = host.readLine();
                        
                             // port:
                             qint16 p;
                             std::cout << "\ninserire la porta: ";
                             std::cin >> p;
                             std::cin.ignore(); 
                        
                             m_client->setHostname(Shost);
                             m_client->setPort(static_cast<quint16>(p));
                        
                             // Try to connect
                             m_client->connectToHost();
                        }
                        
                        void Client::onStateChanged(QMqttClient::ClientState state)
                        {    
                            switch(state) {
                            case QMqttClient::Connected:
                                qDebug()  << "Connected: " << m_client->hostname() << ":" << m_client->port();
                                break;
                            case QMqttClient::Connecting:
                                qDebug()  << "Attempting to connect: " << m_client->hostname() << ":" << m_client->port();
                                break;
                            case QMqttClient::Disconnected:
                                qDebug()  << "Disconnected";
                                break;
                            }
                        }
                        

                        main.cpp

                        #include <QCoreApplication>
                        #include "client.h"
                        
                        int main(int argc, char *argv[])
                        {
                            QCoreApplication a(argc, argv);
                        
                            Client client;
                            client.setup();
                        
                            return a.exec();
                        }
                        

                        @JonB said in MQTT Connection Problem:

                        I have never used MQTT and don't know what it is

                        Network client-server protocol to transmit tiny messages through a network. Nowadays mainly used for IoT device communication, in Industrial 4.0 or in robotics.


                        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                        ~E. W. Dijkstra

                        1 Reply Last reply
                        4

                        12/13

                        11 Sept 2024, 20:51

                        • Login

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