Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. Controllare connessione (ping verso un IP)
Forum Updated to NodeBB v4.3 + New Features

Controllare connessione (ping verso un IP)

Scheduled Pinned Locked Moved Unsolved Italian
9 Posts 2 Posters 756 Views 1 Watching
  • 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.
  • M Offline
    M Offline
    marco_88
    wrote on last edited by
    #1

    Ciao a tutti.

    Sto realizzando un app che deve girare su Raspbian, e fra le cose che faccio ci sono anche delle chiamate verso delle API che in alcuni casi si trovano in una centralina separata.

    Quindi sulla vecchia webapp io controllavo con un plugin javascript chiamato offline.js, la presenza o meno della connessione.

    Nel plugin specificavo qual'era l'IP che dovevo controllare. Faceva un check ogni 5 secondi, e se c'era connessione mostravo un pallino verde sull'interfaccia.

    Anche quando la connessione andava giù e poi tornava su facevo delle cose: per esempio quando tornava facevo di nuovo la chiamata alle API, quando andava giù fermavo i timer, e cose del genere.

    Per l'interfaccia uso QML, e in C++ al momento ho il solo file main.cpp che al momento l'unica cosa che fa è chiamare il file main.qml.

    Essendo nuovo non so neanche come si scambiano informazioni fra c++ e qml (nel caso in qml puro non si possa fare).

    Ve ne sarei grato se mi aiutate a fare questa cosa per controllare se un IP risponde o meno e mostrare questo pallino verde sull'interfaccia.

    Grazie

    1 Reply Last reply
    0
    • guerinoniG Offline
      guerinoniG Offline
      guerinoni
      wrote on last edited by guerinoni
      #2

      @marco_88

      class PingDaemon : public QObject
      {
          Q_OBJECT
      
          Q_PROPERTY(bool connectionIsValid READ connectionIsValid NOTIFY connectionIsValidChanged)
      
      public:
          explicit PingDaemon(QObject *parent = nullptr);
      
          void start(int interval, const QString &host = "8.8.8.8");
          void stop();
      
          bool connectionIsValid() const;
      
      Q_SIGNALS:
          void connectionIsValidChanged();
      
      private Q_SLOTS:
          void ping();
      
      private:
          QTimer m_pingTimer{};
          QString m_currentHost{};
          bool m_connectionIsValid{false};
      };
      
      PingDaemon::PingDaemon(QObject *parent)
          : QObject(parent)
      {
          connect(&m_pingTimer, &QTimer::timeout, this, &PingDaemon::ping);
      
          QProcess p;
          p.start(QStringLiteral("which ping"));
          p.waitForFinished();
      
          if (p.exitCode() == QProcess::CrashExit) {
              throw std::logic_error("Application 'ping' not found.");
          }
      }
      
      void PingDaemon::start(int interval, const QString &host)
      {
          m_currentHost = host;
          m_pingTimer.start(interval * 1000);
          ping();
      }
      
      void PingDaemon::stop()
      {
          m_pingTimer.stop();
      }
      
      bool PingDaemon::connectionIsValid() const
      {
          return m_connectionIsValid;
      }
      
      void PingDaemon::ping()
      {
          const auto host = m_currentHost;
          std::thread([host, this] {
              const auto cmd = "ping -c 1 -W 1 " + host;
              qDebug() << cmd;
              const auto ret = ms::CliUtils::execCmd(cmd);
              const auto currentConnectionStatus = (ret.exitCode == 0);
      
              if (m_connectionIsValid != currentConnectionStatus) {
                  m_connectionIsValid = currentConnectionStatus;
                  Q_EMIT connectionIsValidChanged();
              }
          })
              .detach();
      }
      
      
      1 Reply Last reply
      0
      • M Offline
        M Offline
        marco_88
        wrote on last edited by marco_88
        #3

        Ciao

        Ti ringrazio per la risposta e per il codice che hai postato, però mi dovresti spiegare come usarlo. Io sono nuovo di questo fantastico mondo.

        Prima domanda: questo codice lo devo mettere sul main.cpp o devo creare un nuovo file cpp dove mettere questo codice?

        Seconda domanda: dal mio file main.qml come faccio a ottenere l'informazione sulla connessione? Voglio mettere questo pallino sulla toolbar dell'app.

        Terza domanda: dove specifico l'intervallo per il ping?

        Vorrei che fosse più immediato e veloce possibile a capire se c'è connessione o no. Che il pallino rosso o verde cambi nella maniera più instantanea possibile senza causare rallentamenti all'app. E inoltre dovrei usare questa informazione anche quando richiamo delle request in funzioni javascript che richiamo da QML.

        Grazie

        1 Reply Last reply
        0
        • guerinoniG Offline
          guerinoniG Offline
          guerinoni
          wrote on last edited by
          #4

          @marco_88
          eh diciamo che se non sai il c++ diventa difficile ehehe... Comunque questi due sono un file cpp e un file hpp poi li integri le progetto, istanzi nel main un oggetto di tipo PingDaemon e poi lo esponi in QML, c'e' gia' la property connectionIsValid per verificare la connessione

          1 Reply Last reply
          0
          • M Offline
            M Offline
            marco_88
            wrote on last edited by
            #5

            Ok ora provo. Quindi devo creare 2 file un file lo chiamo checkconnection.cpp e l'altro checkconnection.hpp. Li aggiungo al progetto e dal file main.cpp devo vedere come instanziare questo oggetto PingDaemon. Poi su qml posso sapere se c'è o no connessione usando la propriety connectionIsValid. Tutto corretto a livello teorico?

            1 Reply Last reply
            0
            • M Offline
              M Offline
              marco_88
              wrote on last edited by marco_88
              #6

              Ho modificato il file main.cpp in questo modo:

              #include <QGuiApplication>
              #include <QQmlApplicationEngine>
              #include <QQuickStyle>
              #include <QProcess>
              #include <QThread>
              #include <QDebug>
              #include "checkconnection.h"
              
              int main(int argc, char *argv[])
              {
                  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
              
                  qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
              
                  QGuiApplication app(argc, argv);
                  QQuickStyle::setStyle("Material");
              
                  QQmlApplicationEngine engine;
                  const QUrl url(QStringLiteral("qrc:/main.qml"));
                  QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                   &app, [url](QObject *obj, const QUrl &objUrl) {
                      if (!obj && url == objUrl)
                          QCoreApplication::exit(-1);
                  }, Qt::QueuedConnection);
                  engine.load(url);
              
                  return app.exec();
              }
              
              PingDaemon::PingDaemon(QObject *parent)
                  : QObject(parent)
              {
                  connect(&m_pingTimer, &QTimer::timeout, this, &PingDaemon::ping);
              
                  QProcess p;
                  p.start(QStringLiteral("which ping"));
                  p.waitForFinished();
              
                  if (p.exitCode() == QProcess::CrashExit) {
                      throw std::logic_error("Application 'ping' not found.");
                  }
              }
              
              void PingDaemon::start(int interval, const QString &host)
              {
                  m_currentHost = host;
                  m_pingTimer.start(interval * 1000);
                  ping();
              }
              
              void PingDaemon::stop()
              {
                  m_pingTimer.stop();
              }
              
              bool PingDaemon::connectionIsValid() const
              {
                  return m_connectionIsValid;
              }
              
              void PingDaemon::ping()
              {
                  const auto host = m_currentHost;
                  std::thread([host, this] {
                      const auto cmd = "ping -c 1 -W 1 " + host;
                      qDebug() << cmd;
                      const auto ret = ms::CliUtils::execCmd(cmd);
                      const auto currentConnectionStatus = (ret.exitCode == 0);
              
                      if (m_connectionIsValid != currentConnectionStatus) {
                          m_connectionIsValid = currentConnectionStatus;
                          Q_EMIT connectionIsValidChanged();
                      }
                  })
                      .detach();
              }
              

              Poi ho creato il file checkconnection.h così:

              #ifndef CHECKCONNECTION_H
              #define CHECKCONNECTION_H
              
              #include <QObject>
              #include <QTimer>
              
              class PingDaemon : public QObject
              {
                  Q_OBJECT
              
                  Q_PROPERTY(bool connectionIsValid READ connectionIsValid NOTIFY connectionIsValidChanged)
              
              public:
                  explicit PingDaemon(QObject *parent = nullptr);
              
                  void start(int interval, const QString &host = "8.8.8.8");
                  void stop();
              
                  bool connectionIsValid() const;
              
              Q_SIGNALS:
                  void connectionIsValidChanged();
              
              private Q_SLOTS:
                  void ping();
              
              private:
                  QTimer m_pingTimer{};
                  QString m_currentHost{};
                  bool m_connectionIsValid{false};
              };
              
              #endif
              

              Ma nel file main.cpp ho un errore su questa riga:

              const auto ret = ms::CliUtils::execCmd(cmd);
              

              Mi sottolinea ms:: e mi dice questo:

              use of undeclared identifier ms
              

              Poi mi da un errore anche sulla seguente riga:

              PingDaemon::PingDaemon(QObject *parent)
                  : QObject(parent)
              

              L'errore è il seguente:

              error: undefined reference to `vtable for PingDaemon'
              

              Grazie

              1 Reply Last reply
              0
              • M Offline
                M Offline
                marco_88
                wrote on last edited by marco_88
                #7

                Sono riuscito a compilare, e una volta integrato provo a leggerlo facendo così:

                PingDaemon {
                                id: checkNetwork
                            }
                            Label {
                                horizontalAlignment: Qt.AlignHCenter
                                verticalAlignment: Qt.AlignVCenter
                                color: 'white'
                                font.bold: true
                                text: checkNetwork.connectionIsValid
                            }
                

                Mi risponde sempre false però.

                Ho fatto bee oppure ho sbagliato qualcosa per cercare di leggere lo stato da QML?

                Grazie

                1 Reply Last reply
                0
                • guerinoniG Offline
                  guerinoniG Offline
                  guerinoni
                  wrote on last edited by
                  #8

                  @marco_88
                  Guarda se vuoi posso offrirti supporto tramite altri canali, scrivimi in dm, perche' altrimenti qui diventerebbe un po' lunga la questione... cioe' non sapendo le basi si fa fatica a spiegarsi nei commenti

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    marco_88
                    wrote on last edited by
                    #9

                    Ho fatto progressi:) Fammi sapere però dove sbaglio perchè ricevo sempre false, quando mi aspeteterei true perchè quell'ip se faccio il ping mi risponde.

                    Ho solo cambiato questa parte perchè usando Linux ho letto che per fare il ping si faceva così:

                    void PingDaemon::ping()
                    {
                        const auto host = m_currentHost;
                        std::thread([host, this] {
                            const auto cmd = "ping -c 1 -W 1 " + host;
                            qDebug() << cmd;
                            const auto ret = QProcess::execute(cmd);
                            const auto currentConnectionStatus = (ret == 0);
                    
                            if (m_connectionIsValid != currentConnectionStatus) {
                                m_connectionIsValid = currentConnectionStatus;
                                Q_EMIT connectionIsValidChanged();
                            }
                        })
                            .detach();
                    }
                    

                    Grazie

                    1 Reply Last reply
                    0

                    • Login

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