mirror of
https://github.com/boostorg/mqtt5.git
synced 2025-07-30 12:37:36 +02:00
Add a chapter on maintaing a healthy connection (keep alive, ping, read timeout)
Summary: related to T12804 Reviewers: ivica Reviewed By: ivica Subscribers: miljen, iljazovic Differential Revision: https://repo.mireo.local/D28240
This commit is contained in:
@ -112,7 +112,9 @@
|
|||||||
[include 01_intro.qbk]
|
[include 01_intro.qbk]
|
||||||
[include 02_configuring_the_client.qbk]
|
[include 02_configuring_the_client.qbk]
|
||||||
[include 03_auto_reconnect.qbk]
|
[include 03_auto_reconnect.qbk]
|
||||||
[include 04_examples.qbk]
|
[include 04_maintaining_a_stable_connection.qbk]
|
||||||
|
|
||||||
|
[include 10_examples.qbk]
|
||||||
|
|
||||||
[include examples/Examples.qbk]
|
[include examples/Examples.qbk]
|
||||||
|
|
||||||
|
84
doc/qbk/04_maintaining_a_stable_connection.qbk
Normal file
84
doc/qbk/04_maintaining_a_stable_connection.qbk
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
[section:connection_maintenance Maintaining a stable connection]
|
||||||
|
[nochunk]
|
||||||
|
|
||||||
|
This chapter delves into the strategies used by the __Client__ to sustain a stable connection with the Broker.
|
||||||
|
|
||||||
|
[section:keep_alive Understanding Keep Alive and Server Keep Alive]
|
||||||
|
|
||||||
|
Firstly, it is important to understand `Keep Alive` and `Server Keep Alive` and their role
|
||||||
|
in maintaining a stable connection.
|
||||||
|
|
||||||
|
The MQTT protocol defines a `Keep Alive` value, which is the maximum time interval that is permitted to elapse
|
||||||
|
between the point at which the Client finishes transmitting one packet and the point at which it starts sending the next.
|
||||||
|
In some instances, the Broker might propose a `Server Keep Alive` interval,
|
||||||
|
which the Client should adopt instead of the previously set `Keep Alive` interval (further referred to as the negotiated `Keep Alive` interval).
|
||||||
|
|
||||||
|
If the Client does not transmit any packet within a period equal to `1.5` times the negotiated `Keep Alive` interval,
|
||||||
|
the Broker is required to close the connection to the Client.
|
||||||
|
|
||||||
|
The Client is responsible for ensuring that the interval between packets being sent does not exceed the negotiated `Keep Alive` interval.
|
||||||
|
The __Client__ does this automatically by sending a __PINGREQ__ to the Broker every negotiated `Keep Alive` seconds,
|
||||||
|
independent of any ongoing activity in the connection.
|
||||||
|
|
||||||
|
If the negotiated `Keep Alive` interval is `0`, the Keep Alive mechanism is deactivated, and the __Client__ will *not* send any __PINGREQ__
|
||||||
|
packets. This makes the user responsible for maintaining the connection with the Broker.
|
||||||
|
|
||||||
|
Use [refmem mqtt_client keep_alive] function during the __Client__ configuration phase to specify your preferred `Keep Alive` time in seconds.
|
||||||
|
Otherwise, the __Client__ defaults to a `Keep Alive` period of `60 seconds`.
|
||||||
|
|
||||||
|
[note
|
||||||
|
The MQTT does not use the TCP's built-in keep-alive mechanism as it is inflexible and limited in that it can be configured solely at the operating system level.
|
||||||
|
The default time a connection must be idle before sending the first keep-alive packet is typically set to 2 hours,
|
||||||
|
exceeding the tolerances of most MQTT applications.
|
||||||
|
]
|
||||||
|
|
||||||
|
[endsect] [/keep_alive]
|
||||||
|
|
||||||
|
[section:half_open_connections Detecting and handling half-open connections]
|
||||||
|
|
||||||
|
Ensuring the integrity and stability of network connections is a complex task,
|
||||||
|
given the number of potential disruptions such as software anomalies,
|
||||||
|
hardware failures, signal loss, router complications, interruptions in the connectivity path, and more.
|
||||||
|
A robust Client implementation must accurately detect and resolve such disruptions despite the inherent difficulty in identifying them.
|
||||||
|
|
||||||
|
Under normal circumstances, when one side wants to close the TCP connection, a TCP termination procedure, or a 4-way handshake, is initiated.
|
||||||
|
The initiating side sends a TCP packet indicating the end of data transmission to finish a TCP connection, which is then acknowledged by the receiver.
|
||||||
|
The receiver, in turn, sends the same termination packet, receiving an acknowledgement from the initiating side to conclude the process.
|
||||||
|
This ensures both sides have finished sending and receiving all data and agree to close the connection gracefully.
|
||||||
|
|
||||||
|
However, the connection may be abruptly terminated due to external disturbances.
|
||||||
|
For example, consider a situation in which the Client communicates with a Broker but suddenly experiences an unexpected signal loss.
|
||||||
|
Considering neither side initiated a 4-way handshake to close the connection,
|
||||||
|
the Client has no reason to perceive the connection as anything but open.
|
||||||
|
Consequently, it will continue to send packets to the Broker and await responses,
|
||||||
|
oblivious that the packets would never reach the Broker on the other end.
|
||||||
|
This results in a half-open TCP connection scenario,
|
||||||
|
where the connection is effectively terminated on one end but remains active on the other.
|
||||||
|
|
||||||
|
Without any mechanisms in place to identify half-open connections, the Client risks
|
||||||
|
remaining in a half-open state indefinitely.
|
||||||
|
A common strategy to address a half-open state is to incorporate a timeout mechanism.
|
||||||
|
Within this strategy, the Client anticipates receiving some data from the Broker within a predefined
|
||||||
|
timeout interval.
|
||||||
|
Successful data reception within this interval affirms that the connection is active and stable.
|
||||||
|
However, if no data is received within the timeout interval, the Client will close the connection, presuming network failure.
|
||||||
|
Consequently, if the Client is in the half-open state, then no data will come through to it, and the connection will time out.
|
||||||
|
This condition triggers the Client to initiate the reconnection procedure to try to restore the severed connection.
|
||||||
|
|
||||||
|
To avoid false detections of a half-open state in idle connections, the Client must ensure consistent data exchange.
|
||||||
|
This is achieved through periodic __PINGREQ__ packets sent by the Client to the Broker,
|
||||||
|
which responds with __PINGRESP__ packet, affirming its operational status.
|
||||||
|
|
||||||
|
The __Client__ will dispatch a __PINGREQ__ at an interval equal to the negotiated `Keep Alive` seconds and expects
|
||||||
|
to receive some data
|
||||||
|
[footnote The __Client__ does not require to specifically receive __PINGRESP__ to its __PINGREQ__. Any data from the Broker will suffice to confirm its status.]
|
||||||
|
from the Broker within `1.5` times the negotiated `Keep Alive` seconds.
|
||||||
|
If no data is received within this time, the __Client__ will assume a half-open state and initiate a reconnect procedure
|
||||||
|
described in the [link async_mqtt5.auto_reconnect Built-in auto-reconnect and retry mechanism].
|
||||||
|
|
||||||
|
[important If the negotiated `Keep Alive` value is set to `0`, the timeout mechanism to detect half-open connection
|
||||||
|
is disabled. As a result, the __Client__ loses its capability to identify and adequately respond to half-open scenarios.]
|
||||||
|
|
||||||
|
[endsect] [/half_open_connections]
|
||||||
|
|
||||||
|
[endsect] [/connection_maintenance]
|
@ -31,4 +31,3 @@ The following list contains all the examples that showcase how to use the __Clie
|
|||||||
]
|
]
|
||||||
|
|
||||||
[endsect][/examples]
|
[endsect][/examples]
|
||||||
|
|
Reference in New Issue
Block a user