diff --git a/src/MQTTAsync.c b/src/MQTTAsync.c index c6a11f6d3..5e0d3f6a2 100644 --- a/src/MQTTAsync.c +++ b/src/MQTTAsync.c @@ -645,7 +645,7 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options) m->connect.onFailure5 = options->onFailure5; } m->connect.context = options->context; - m->connectTimeout = options->connectTimeout; + m->connectTimeoutMs = options->connectTimeout * 1000; /* don't lock async mutex if we are being called from a callback */ thread_id = Paho_thread_getid(); @@ -679,8 +679,27 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options) if (options->struct_version >= 4) { m->automaticReconnect = options->automaticReconnect; - m->minRetryInterval = options->minRetryInterval; - m->maxRetryInterval = options->maxRetryInterval; + // Old retry time params were in seconds, but we want to support + // millisecond min retry intervals. + // To remain backwards compatible, if the param is under 100, we + // assume it's in seconds, otherwise, milliseconds. + if (options->minRetryInterval < 100) + { + m->minRetryIntervalMs = options->minRetryInterval * 1000; + } + else + { + m->minRetryIntervalMs = options->minRetryInterval; + } + // Similar for max interval, if it's under 1000, we assume seconds + if (options->maxRetryInterval < 1000) + { + m->maxRetryIntervalMs = options->maxRetryInterval * 1000; + } + else + { + m->maxRetryIntervalMs = options->maxRetryInterval; + } } if (options->struct_version >= 7) { @@ -847,7 +866,7 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options) m->c->retryInterval = options->retryInterval; m->shouldBeConnected = 1; - m->connectTimeout = options->connectTimeout; + m->connectTimeoutMs = options->connectTimeout * 1000; MQTTAsync_freeServerURIs(m); if (options->struct_version >= 2 && options->serverURIcount > 0) @@ -949,8 +968,8 @@ int MQTTAsync_reconnect(MQTTAsync handle) if (m->shouldBeConnected) { m->reconnectNow = 1; - m->currentIntervalBase = m->minRetryInterval; - m->currentInterval = m->minRetryInterval; + m->currentIntervalBaseMs = m->minRetryIntervalMs; + m->currentIntervalMs = m->minRetryIntervalMs; m->retrying = 1; rc = MQTTASYNC_SUCCESS; } diff --git a/src/MQTTAsync.h b/src/MQTTAsync.h index e11af0482..39bfc1a39 100644 --- a/src/MQTTAsync.h +++ b/src/MQTTAsync.h @@ -1267,6 +1267,9 @@ typedef struct const char* password; /** * The time interval in seconds to allow a connect to complete. + * The time interval in milliseconds to allow a connect to complete. + * For backwards compatibility and consistency with the retry intervals + * this is considered to be seconds if it is under 1000. */ int connectTimeout; /** @@ -1324,15 +1327,25 @@ typedef struct */ int MQTTVersion; /** - * Reconnect automatically in the case of a connection being lost. 0=false, 1=true + * Reconnect automatically in the case of a connection being lost? + * This retries with exponential backoff starting from the minRetryInterval + * up to the maxRetryInterval, +/- 20% random jitter. */ int automaticReconnect; /** - * The minimum automatic reconnect retry interval in seconds. Doubled on each failed retry. + * Minimum retry interval in milliseconds. Doubled on each failed retry. + * For backwards compatibility, if the value is under 100, + * it is assumed to be in seconds rather than milliseconds. + * Random jitter is applied to the value with +/- 20% */ int minRetryInterval; /** - * The maximum automatic reconnect retry interval in seconds. The doubling stops here on failed retries. + * Maximum retry interval in milliseconds. The doubling stops here on failed retries. + * For backwards compatibility, if the value is under 1000, + * it is assumed to be in seconds rather than milliseconds. + * Note: due to random jitter, the actual max time interval could be as much as 20% higher, + * but this will change on each retry. + * e.g. for maxRetryInterval of 60 seconds, the actual wait time could be anywhere from 48 to 72 seconds */ int maxRetryInterval; /** diff --git a/src/MQTTAsyncUtils.c b/src/MQTTAsyncUtils.c index 6d9330403..245b5294d 100644 --- a/src/MQTTAsyncUtils.c +++ b/src/MQTTAsyncUtils.c @@ -923,14 +923,14 @@ void MQTTAsync_startConnectRetry(MQTTAsyncs* m) m->lastConnectionFailedTime = MQTTTime_start_clock(); if (m->retrying) { - m->currentIntervalBase = min(m->currentIntervalBase * 2, m->maxRetryInterval); + m->currentIntervalBaseMs = min(m->currentIntervalBaseMs * 2, m->maxRetryIntervalMs); } else { - m->currentIntervalBase = m->minRetryInterval; + m->currentIntervalBaseMs = m->minRetryIntervalMs; m->retrying = 1; } - m->currentInterval = MQTTAsync_randomJitter(m->currentIntervalBase, m->minRetryInterval, m->maxRetryInterval); + m->currentIntervalMs = MQTTAsync_randomJitter(m->currentIntervalBaseMs, m->minRetryIntervalMs, m->maxRetryIntervalMs); } } @@ -1701,7 +1701,7 @@ static void MQTTAsync_checkTimeouts(void) MQTTAsync_checkDisconnect(m, &m->disconnect); /* check connect timeout */ - if (m->c->connect_state != NOT_IN_PROGRESS && MQTTTime_elapsed(m->connect.start_time) > (ELAPSED_TIME_TYPE)(m->connectTimeout * 1000)) + if (m->c->connect_state != NOT_IN_PROGRESS && MQTTTime_elapsed(m->connect.start_time) > (ELAPSED_TIME_TYPE)(m->connectTimeoutMs)) { nextOrClose(m, MQTTASYNC_FAILURE, "TCP connect timeout"); continue; @@ -1715,7 +1715,7 @@ static void MQTTAsync_checkTimeouts(void) if (m->automaticReconnect && m->retrying) { - if (m->reconnectNow || MQTTTime_elapsed(m->lastConnectionFailedTime) > (ELAPSED_TIME_TYPE)(m->currentInterval * 1000)) + if (m->reconnectNow || MQTTTime_elapsed(m->lastConnectionFailedTime) > (ELAPSED_TIME_TYPE)(m->currentIntervalMs)) { /* to reconnect put the connect command to the head of the command queue */ MQTTAsync_queuedCommand* conn = malloc(sizeof(MQTTAsync_queuedCommand)); diff --git a/src/MQTTAsyncUtils.h b/src/MQTTAsyncUtils.h index 0e08beac1..72576d1a1 100644 --- a/src/MQTTAsyncUtils.h +++ b/src/MQTTAsyncUtils.h @@ -126,16 +126,16 @@ typedef struct MQTTAsync_struct int shouldBeConnected; int noBufferedMessages; /* the current number of buffered (publish) messages for this client */ - /* added for automatic reconnect */ + /* added for automatic reconnect, intervals are in MS */ int automaticReconnect; - int minRetryInterval; - int maxRetryInterval; + int minRetryIntervalMs; + int maxRetryIntervalMs; int serverURIcount; char** serverURIs; - int connectTimeout; + int connectTimeoutMs; - int currentInterval; - int currentIntervalBase; + int currentIntervalMs; + int currentIntervalBaseMs; START_TIME_TYPE lastConnectionFailedTime; int retrying; int reconnectNow;