Before thinking about connection timeout, we need to define what a connection is. Here is a typical connection sequence:

  1. am::async_underlying_handshake (resolves hostname, TCP, TLS, and WebSocket handshake if required)

  2. Send MQTT CONNECT packet

  3. Receive MQTT CONNACK packet

Typically, the user can set a timer before Step 1 and cancel the timer after Step 3. If the timer expires, call the close() function.

PINGRESP timeout

After the MQTT connection is established (Step 3 is finished successfully), if the underlying connection is disconnected, then the recv() function returns an error. However, if the broker is frozen or the disconnect is not detected but actually disconnected, the client needs to know the status of the connection.

In this case, you can use set_pingresp_recv_timeout() and send a PINGREQ packet.

set_pingresp_recv_timeout()

The parameter is in milliseconds. You need to call this function before sending the MQTT CONNECT packet. The timer is automatically set when the PINGREQ packet is sent. If a PINGRESP packet is received from the broker, the timer is canceled. If the timer expires, the connection is disconnected from the client side. Finally, the client gets an error from the async_recv() function.

sending PINGREQ packet

You can create a PINGREQ packet and send it manually. Alternatively, you can set the keep_alive value in the CONNECT packet to a value greater than 0. Then, the client will automatically start sending PINGREQ packets if the keep_alive seconds pass without any packet being sent.

Note
If keep_alive is set to a value greater than 0, the broker also starts checking the client connection status. If the broker doesn’t receive any packet from the client during keep_alive * 1.5 seconds, the connection is closed by the broker.