Merge PR #416: Better cloud reconnect
This commit is contained in:
commit
2b6d1b6f5a
@ -50,6 +50,17 @@ AWSConnector::AWSConnector(QObject *parent) : QObject(parent)
|
|||||||
|
|
||||||
m_reconnectTimer.setSingleShot(true);
|
m_reconnectTimer.setSingleShot(true);
|
||||||
connect(&m_reconnectTimer, &QTimer::timeout, this, &AWSConnector::doConnect);
|
connect(&m_reconnectTimer, &QTimer::timeout, this, &AWSConnector::doConnect);
|
||||||
|
|
||||||
|
// In rare circumstances (I've observed this when the wifi driver panics) it happens that a connection
|
||||||
|
// attempt never completes but also doesn't emit any error (bug in Qt?). To catch that, manually call the
|
||||||
|
// disconnected slot to trigger reconnecting.
|
||||||
|
m_connectTimer.setSingleShot(true);
|
||||||
|
connect(&m_connectTimer, &QTimer::timeout, this, [this](){
|
||||||
|
if (m_client && !m_client->isConnected()) {
|
||||||
|
qCWarning(dcAWS()) << "Connection guard timer timed out! Resetting connection.";
|
||||||
|
onDisconnected();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
AWSConnector::~AWSConnector()
|
AWSConnector::~AWSConnector()
|
||||||
@ -63,6 +74,14 @@ AWSConnector::~AWSConnector()
|
|||||||
|
|
||||||
void AWSConnector::connect2AWS(const QString &endpoint, const QString &clientId, const QString &clientName, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile)
|
void AWSConnector::connect2AWS(const QString &endpoint, const QString &clientId, const QString &clientName, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile)
|
||||||
{
|
{
|
||||||
|
if (m_client) {
|
||||||
|
qCDebug(dcAWS()) << "Cleaning up old connection";
|
||||||
|
m_shouldReconnect = false;
|
||||||
|
m_client->disconnectFromHost();
|
||||||
|
// Don't rely on the graceful disconnect to actually happen... Force cleanup of the old connection
|
||||||
|
onDisconnected();
|
||||||
|
}
|
||||||
|
|
||||||
m_shouldReconnect = true;
|
m_shouldReconnect = true;
|
||||||
m_currentEndpoint = endpoint;
|
m_currentEndpoint = endpoint;
|
||||||
m_caFile = caFile;
|
m_caFile = caFile;
|
||||||
@ -71,12 +90,6 @@ void AWSConnector::connect2AWS(const QString &endpoint, const QString &clientId,
|
|||||||
m_clientId = clientId;
|
m_clientId = clientId;
|
||||||
m_clientName = clientName;
|
m_clientName = clientName;
|
||||||
|
|
||||||
if (m_client) {
|
|
||||||
m_client->disconnectFromHost();
|
|
||||||
qCDebug(dcAWS()) << "Disconnecting from AWS";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
doConnect();
|
doConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,6 +134,7 @@ void AWSConnector::doConnect()
|
|||||||
connect(m_client, &MqttClient::connected, this, &AWSConnector::onConnected);
|
connect(m_client, &MqttClient::connected, this, &AWSConnector::onConnected);
|
||||||
connect(m_client, &MqttClient::disconnected, this, &AWSConnector::onDisconnected);
|
connect(m_client, &MqttClient::disconnected, this, &AWSConnector::onDisconnected);
|
||||||
connect(m_client, &MqttClient::error, this, [this](const QAbstractSocket::SocketError error){
|
connect(m_client, &MqttClient::error, this, [this](const QAbstractSocket::SocketError error){
|
||||||
|
m_connectTimer.stop();
|
||||||
qCWarning(dcAWS()) << "An error happened in the MQTT transport" << error;
|
qCWarning(dcAWS()) << "An error happened in the MQTT transport" << error;
|
||||||
// In order to also call onDisconnected (and start the reconnect timer) even when we have never been connected
|
// In order to also call onDisconnected (and start the reconnect timer) even when we have never been connected
|
||||||
// we'll call it here. However, that might cause onDisconnected to be called twice. Let's prevent that.
|
// we'll call it here. However, that might cause onDisconnected to be called twice. Let's prevent that.
|
||||||
@ -131,10 +145,15 @@ void AWSConnector::doConnect()
|
|||||||
connect(m_client, &MqttClient::subscribed, this, &AWSConnector::onSubscribed);
|
connect(m_client, &MqttClient::subscribed, this, &AWSConnector::onSubscribed);
|
||||||
connect(m_client, &MqttClient::publishReceived, this, &AWSConnector::onPublishReceived);
|
connect(m_client, &MqttClient::publishReceived, this, &AWSConnector::onPublishReceived);
|
||||||
connect(m_client, &MqttClient::published, this, &AWSConnector::onPublished);
|
connect(m_client, &MqttClient::published, this, &AWSConnector::onPublished);
|
||||||
|
|
||||||
|
// If none of the above slots are called within a minute, reset ourselves...
|
||||||
|
m_connectTimer.start(60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AWSConnector::onConnected()
|
void AWSConnector::onConnected()
|
||||||
{
|
{
|
||||||
|
m_connectTimer.stop();
|
||||||
|
|
||||||
if (!readRegisteredFlag()) {
|
if (!readRegisteredFlag()) {
|
||||||
qCDebug(dcAWS()) << "AWS connected. Device not registered yet. Registering...";
|
qCDebug(dcAWS()) << "AWS connected. Device not registered yet. Registering...";
|
||||||
registerDevice();
|
registerDevice();
|
||||||
@ -286,6 +305,8 @@ quint16 AWSConnector::publish(const QString &topic, const QVariantMap &message)
|
|||||||
|
|
||||||
void AWSConnector::onDisconnected()
|
void AWSConnector::onDisconnected()
|
||||||
{
|
{
|
||||||
|
m_connectTimer.stop();
|
||||||
|
|
||||||
qCDebug(dcAWS) << "AWS disconnected.";
|
qCDebug(dcAWS) << "AWS disconnected.";
|
||||||
m_client->deleteLater();
|
m_client->deleteLater();
|
||||||
m_client = nullptr;
|
m_client = nullptr;
|
||||||
|
|||||||
@ -113,6 +113,7 @@ private:
|
|||||||
bool m_isCleanSession = true;
|
bool m_isCleanSession = true;
|
||||||
bool m_shouldReconnect = false;
|
bool m_shouldReconnect = false;
|
||||||
QTimer m_reconnectTimer;
|
QTimer m_reconnectTimer;
|
||||||
|
QTimer m_connectTimer;
|
||||||
|
|
||||||
quint8 m_transactionId = 0;
|
quint8 m_transactionId = 0;
|
||||||
QString m_createDeviceId;
|
QString m_createDeviceId;
|
||||||
|
|||||||
Reference in New Issue
Block a user