From 679afbc5bc6deba44bc84836466a4a64e184a84e Mon Sep 17 00:00:00 2001 From: Harsh Gandhi <63674702+HarshGandhi-AWS@users.noreply.github.com> Date: Thu, 2 Sep 2021 20:36:05 -0700 Subject: [PATCH] Retry connection after getting disconnected from server. (#168) * Set TCP keep alive and reset connection configurations for devices * update version * updated onConnectionResumed method * remove tcp keep alive * Updated log statements * updated version. --- source/SharedCrtResourceManager.cpp | 47 +++++++++++++++++++++++++++-- source/SharedCrtResourceManager.h | 5 ++- source/main.cpp | 11 +++---- source/util/Retry.cpp | 2 +- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/source/SharedCrtResourceManager.cpp b/source/SharedCrtResourceManager.cpp index 07a99ecc..e8fdb6b0 100644 --- a/source/SharedCrtResourceManager.cpp +++ b/source/SharedCrtResourceManager.cpp @@ -21,8 +21,9 @@ using namespace Aws::Iot::DeviceClient::Logging; constexpr int SharedCrtResourceManager::DEFAULT_WAIT_TIME_SECONDS; -bool SharedCrtResourceManager::initialize(const PlainConfig &config) +bool SharedCrtResourceManager::initialize(const PlainConfig &config, vector *featuresList) { + features = featuresList; initializeAllocator(); initialized = buildClient(config) == SharedCrtResourceManager::SUCCESS; return initialized; @@ -167,6 +168,7 @@ int SharedCrtResourceManager::establishConnection(const PlainConfig &config) clientConfigBuilder.WithCertificateAuthority(config.rootCa->c_str()); clientConfigBuilder.WithSdkName(SharedCrtResourceManager::BINARY_NAME); clientConfigBuilder.WithSdkVersion(SharedCrtResourceManager::BINARY_VERSION); + auto clientConfig = clientConfigBuilder.Build(); if (!clientConfig) @@ -222,11 +224,43 @@ int SharedCrtResourceManager::establishConnection(const PlainConfig &config) } }; + /* + * Invoked when connection is interrupted. + */ + auto OnConnectionInterrupted = [&](Mqtt::MqttConnection &, int errorCode) { + { + if (errorCode) + { + LOGM_ERROR( + TAG, + "MQTT Connection interrupted with error: `%s`. Device Client will retry connection until it is " + "successfully connected to the core. ", + ErrorDebugString(errorCode)); + } + } + }; + + /* + * Invoked when connection is resumed. + */ + auto OnConnectionResumed = [&](Mqtt::MqttConnection &, int returnCode, bool) { + { + LOGM_INFO(TAG, "MQTT connection resumed with return code: %d", returnCode); + } + }; + connection->OnConnectionCompleted = move(onConnectionCompleted); connection->OnDisconnect = move(onDisconnect); + connection->OnConnectionInterrupted = move(OnConnectionInterrupted); + connection->OnConnectionResumed = move(OnConnectionResumed); LOGM_INFO(TAG, "Establishing MQTT connection with client id %s...", config.thingName->c_str()); - if (!connection->Connect(config.thingName->c_str(), true, 0)) + if (!connection->SetReconnectTimeout(15, 240)) + { + LOG_ERROR(TAG, "Device Client is not able to set reconnection settings. Device Client will retry again."); + return RETRY; + } + if (!connection->Connect(config.thingName->c_str(), false)) { LOGM_ERROR(TAG, "MQTT Connection failed with error: %s", ErrorDebugString(connection->LastError())); return RETRY; @@ -306,3 +340,12 @@ void SharedCrtResourceManager::disconnect() LOG_ERROR(TAG, "MQTT Connection failed to disconnect"); } } + +void SharedCrtResourceManager::startDeviceClientFeatures() +{ + LOG_INFO(TAG, "Starting Device Client features."); + for (auto *feature : *features) + { + feature->start(); + } +} \ No newline at end of file diff --git a/source/SharedCrtResourceManager.h b/source/SharedCrtResourceManager.h index 287c8c52..c88aca2e 100644 --- a/source/SharedCrtResourceManager.h +++ b/source/SharedCrtResourceManager.h @@ -4,6 +4,7 @@ #ifndef DEVICE_CLIENT_SHAREDCRTRESOURCEMANAGER_H #define DEVICE_CLIENT_SHAREDCRTRESOURCEMANAGER_H +#include "Feature.h" #include "config/Config.h" #include @@ -41,6 +42,7 @@ namespace Aws std::unique_ptr mqttClient; std::shared_ptr connection; struct aws_allocator *allocator; + std::vector *features; bool locateCredentials(const PlainConfig &config); int buildClient(const PlainConfig &config); @@ -50,9 +52,10 @@ namespace Aws static const int SUCCESS = 0; static const int RETRY = 1; static const int ABORT = 2; - bool initialize(const PlainConfig &config); + bool initialize(const PlainConfig &config, std::vector *features); void initializeAWSHttpLib(); int establishConnection(const PlainConfig &config); + void startDeviceClientFeatures(); std::shared_ptr getConnection(); Aws::Crt::Io::EventLoopGroup *getEventLoopGroup(); struct aws_allocator *getAllocator(); diff --git a/source/main.cpp b/source/main.cpp index 857a6a28..8b63db8f 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -283,7 +283,7 @@ int main(int argc, char *argv[]) shared_ptr listener = shared_ptr(new DefaultClientBaseNotifier); resourceManager = shared_ptr(new SharedCrtResourceManager); - if (!resourceManager.get()->initialize(config.config)) + if (!resourceManager.get()->initialize(config.config, &features)) { LOGM_ERROR( TAG, @@ -300,7 +300,7 @@ int main(int argc, char *argv[]) { /* - * Establish MQTT connection using claim certificates and private key to provision device/thing. + * Establish MQTT connection using claim certificates and private key to provision the device/thing. */ # if !defined(DISABLE_MQTT) attemptConnection(); @@ -316,7 +316,7 @@ int main(int argc, char *argv[]) { LOGM_ERROR( TAG, - "*** %s: Failed to Provision thing or Validate newly created resources. " + "*** %s: Failed to Provision thing or validate newly created resources. " "Please verify your AWS IoT credentials, " "configuration, Fleet Provisioning Template, claim certificate and policy used. ***", DC_FATAL_ERROR); @@ -428,10 +428,7 @@ int main(int argc, char *argv[]) # endif #endif - for (auto &feature : features) - { - feature->start(); - } + resourceManager->startDeviceClientFeatures(); featuresReadWriteLock.unlock(); // UNLOCK // Now allow this thread to sleep until it's interrupted by a signal diff --git a/source/util/Retry.cpp b/source/util/Retry.cpp index d2b309be..fa493964 100644 --- a/source/util/Retry.cpp +++ b/source/util/Retry.cpp @@ -35,7 +35,7 @@ bool Retry::exponentialBackoff( if (config.maxRetries < 0) { - LOG_DEBUG(TAG, "Retryable function will retry until success"); + LOG_DEBUG(TAG, "Retryable function starting, it will retry until success"); } bool successful = false;