emqtt icon indicating copy to clipboard operation
emqtt copied to clipboard

Client does not disconnect from broker if keepalive ping gets no response (heartbeat timeout)

Open srijan opened this issue 2 years ago • 2 comments

The purpose of keepalive is to periodically send a ping packet (and check for it's response) so that both sides of the connection know when the connection fails, and they can close the old connection and try to connect again.

In the current implementation, emqtt sends the PINGREQ packet at keepalive intervals (if configured), but does not check that PINGRESP is coming correctly. So, in case the connection breaks / hangs, emqtt does not fail.

How to reproduce:

  1. Run emqtt on local system and connect to emqx (or any other broker) running on cloud with keepalive = 10 seconds (or any low value).
  2. Disconnect from WiFi/Network ( or simulate connection hang in some other way )
  3. emqtt does not give connection failure even after several minutes

Expected behavior: If no ping response is received from broker after keepalive*3 seconds, disconnect from broker. Then the retry logic can try to reconnect, if configured.

The actual heartbeat timeout value can also be created as a config similar to emqx's keepalive_backoff.

srijan avatar May 11 '22 02:05 srijan

My recommended implementation:

  1. Keep track of last packet received time for any packet in a new state variable.
  2. Start a new timer which checks this last packet received time periodically
  3. If last packet received time > Keepalive * backoff * 2, then consider the connection failed.

If this is acceptable, I can raise a PR. Comments welcome.

srijan avatar May 11 '22 02:05 srijan

I see the same: After a disconnect, there is no disconnect notice/error from the emqtt lib.

emiltin avatar Jan 17 '24 14:01 emiltin