I use QTimer to send periodically \'Ping\' packet to the server (MQTT client). But it timer is not absolutely accurate. After some time of working it has some delay and server b
#pragma once
#include <cstdint>
#include <QObject>
class PrecisePolling : public QObject
{
Q_OBJECT
private:
std::uint64_t previousPollingTime;
public:
PrecisePolling();
public slots:
void doPolling();
#include "precisepolling.h"
#include "QDateTime"
#include <QDebug>
PrecisePolling::PrecisePolling()
: previousPollingTime(QDateTime::currentMSecsSinceEpoch())
{}
void PrecisePolling::doPolling()
{
const std::uint64_t ms = QDateTime::currentMSecsSinceEpoch();
qDebug() << ms - previousPollingTime;
previousPollingTime = ms;
}
#include <QCoreApplication>
#include <QThread>
#include <QTimer>
#include "precisepolling.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QThread thread;
QTimer timer;
PrecisePolling pp;
timer.setInterval(1000);
timer.setTimerType(Qt::PreciseTimer);
QObject::connect(&timer, &QTimer::timeout, &pp, &PrecisePolling::doPolling);
timer.start();
timer.moveToThread(&thread);
pp.moveToThread(&thread);
thread.start(QThread::Priority::TimeCriticalPriority);
return a.exec();
}
Run a QTimer on a separate QThread which doesn't do anything else. If you're running the timer on an already busy thread the timeout events may not come on time or not at all.
Make a worker class e.g. "PingPacketWorker", implement a slot that does pinging. Make a QThread. Connect your QTimer and PingPacketWorker signal/slots. Start the timer. Call moveToThread on the PingPacketWorker and the QTimer, the timer should restart because of moveToThread, note you can only start / stop it on the owner thread!
You could also increase your QThread's priority since you asked for "the most accurate" solution ...
Update:
Also, set QTimer::setTimerType(Qt::PreciseTimer)
The default Qt::CoarseTimer is less precise (5% of the interval)