coreMQTT v2.0.0
MQTT 3.1.1 Client Library
Timeouts in coreMQTT library

Information about timeouts that coreMQTT library relies on.

The coreMQTT library relies on timeouts to handle MQTT keep-alive mechanism and Transport Send and Receive operations. Timeouts must be configured correctly for ensuring the expected behavior of the application using the coreMQTT library. The timeouts and the recommended configurations are listed below.

  1. Transport Send and Receive timeouts
  2. MQTT Keep Alive interval
  3. MQTT Ping Response timeout
  4. MQTT Receive Polling timeout
  5. MQTT Send Retry timeout
  6. Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs
  7. Timeout for MQTT_Connect

Transport Send and Receive timeouts

These are the network send and read operation blocking timeouts used by the implementation of Transport Send and Transport Receive functions, respectively, that are supplied to the coreMQTT library. Transport Send and Receive timeouts must be configured by the application for the Transport interface implementation provided to the coreMQTT library. If it is essential to send more data than the size of the TCP buffer, then the Transport Send timeout can be set to a bigger value than that of cases in which size of the data to be sent is smaller than the TCP buffer, so as to efficiently wait for the TCP buffer to be available to copy the data from MQTT buffers.

We recommend using a relatively smaller value for these timeouts as compared to the MQTT Keep Alive interval, so as to make sure that an MQTT Control packet including an MQTT ping request packet can be sent to the Server even within the Keep Alive interval, even if the Transport functions block for the maximum time.

See also
Transport Interface

MQTT Keep Alive interval

MQTT Keep Alive interval is the maximum time interval that is permitted to elapse between the point at which the MQTT Client finishes transmitting one Control Packet and the point it starts sending the next. If the Server does not receive a Control Packet from the Client within one and a half times the Keep Alive time period, it will disconnect the MQTT connection to the Client.

If MQTT_ProcessLoop function is used to manage keep alive in the application, the MQTT Keep Alive interval must be configured to be a value larger than that of the Transport Send and Receive timeouts. This is to make sure that a Control packet including an MQTT ping request packet can be sent to the Server even if the Transport functions block for the maximum time. MQTT Keep Alive interval can be configured by setting the keepAliveIntervalSec member of the MQTTContext_t structure.

See also
Keep-Alive

MQTT Ping Response timeout

MQTT Ping Response timeout is the time to wait for a ping response to an MQTT ping request as part of the keep-alive mechanism in the MQTT Client. This timeout can be configured independent of the Transport timeouts unlike the MQTT Keep Alive interval, since this timeout only depends on the MQTT broker, the platform and the network latencies.

We recommend to choose a ping response timeout by experimenting with an MQTT application on a sample of devices and collecting the data of latency for each ping response from the broker after a ping request is sent. A timeout value can then be chosen based on the statistical measure suitable for the end application, such as 99th percentile or average.

MQTT Ping Response timeout can be set by defining the configuration MQTT_PINGRESP_TIMEOUT_MS.

MQTT Receive Polling timeout

MQTT Receive Polling timeout is the maximum duration between non-empty network reads while receiving an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions. This timeout represents the maximum polling duration that is allowed without any data reception from the network for the incoming packet.

It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility of partial data being received. If you have small TCP buffers and a high latency network, the optimum value for the timeout can be surprisingly long. In such cases, optimum value for the timeout can be better determined based on experimenting the MQTT applications with payloads bigger than the TCP buffer. If a retry is required for a Transport Receive even after hitting a timeout of Transport Receive without any data received, we recommend using a value larger than the Transport Receive timeout. If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, that always returns 0, is used, then this timeout must be set to 0.

The MQTT Receive Polling timeout can be set by defining the configuration MQTT_RECV_POLLING_TIMEOUT_MS.

MQTT Send Retry timeout

MQTT Send Retry timeout is the maximum duration between non-empty network transmissions while sending an MQTT packet via the MQTT_ProcessLoop or MQTT_ReceiveLoop API functions. This timeout represents the maximum duration that is allowed for no data transmission over the network through the Transport Send function.

It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility of partial data being sent. If you have small TCP buffers and a high latency network, the optimum value for the timeout can be surprisingly long. In such cases, optimum value for the timeout can be better determined based on experimenting the MQTT applications with payloads bigger than the TCP buffer. If a retry is required for a Transport Send even after hitting a timeout of Transport Send before any data could be sent to transport layer, we recommend using a value larger than the Transport Send timeout. If a dummy implementation of the MQTTGetCurrentTimeFunc_t timer function, that always returns 0, is used, then this timeout must be set to 0.

The MQTT Send Retry timeout can be set by defining the configuration MQTT_SEND_RETRY_TIMEOUT_MS.

Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs

This timeout is passed as an argument to MQTT_ProcessLoop or MQTT_ReceiveLoop API functions. It is the minimum time that the receive loop in these API functions will run, unless an error occurs. These APIs may be blocked for more time than this timeout, since the APIs will attempt to send and receive MQTT packets to the network using the Transport implementation. The maximum time spent on Transport functions for send and receive depends on the Transport Send and Receive timeouts and the MQTT Receive Polling timeouts as explained in the descriptions of these timeouts above.

Passing a timeout value of 0 will run these APIs for a single iteration. The other timeouts mentioned thus far ensure you don't disconnect the MQTT just because the network is slow or buffers get full. They are necessary because coreMQTT has no 'memory' of being half way through a packet and will just error and disconnect if you don't give enough time for incoming or outgoing packet delivery. That means, especially in multi-threaded application, the process loop timeout can be zero.

MQTT_ProcessLoop API can be used to manage the MQTT keep-alive mechanism and if used, application must invoke this API faster than the MQTT Keep Alive interval. If a dummy MQTTGetCurrentTimeFunc_t was passed to MQTT_Init, then the keep-alive mechanism is not supported by the MQTT_ProcessLoop API; instead the MQTT_ReceiveLoop should be used.

See also
Runtime Timeouts passed to MQTT library

Timeout for MQTT_Connect

This timeout is passed as an argument to MQTT_Connect. It is the maximum time to wait for an MQTT CONNACK packet. If this value is set to 0, then instead of a time-based loop, it will attempt to call the Transport Receive function up to a maximum number of retries, which is defined by MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.

We recommend to choose a timeout for MQTT_Connect by experimenting with an MQTT application on a sample of devices and collecting the data of latency for each CONNACK packet received from the broker after an MQTT CONNECT packet is sent. A timeout value can then be chosen based on the statistical measure suitable for the end application, such as 99th percentile or average.

See also
Runtime Timeouts passed to MQTT library