From cead6af86b66f20bd85111ba16235efe19851dd3 Mon Sep 17 00:00:00 2001 From: Pierre Fersing Date: Sun, 7 Jan 2024 15:54:58 +0100 Subject: [PATCH] Fix is_connected property when not using loop_forever --- ChangeLog.txt | 4 ++++ src/paho/mqtt/client.py | 15 +++++++++++++++ src/paho/mqtt/enums.py | 1 + 3 files changed, 20 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 0e13b7d0..eabcd625 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -23,6 +23,10 @@ v2.0.0 - 2023-xx-xx - Fix loading too weak TLS CA file but setting allowed ciphers before loading CA. Closes #676. - Allow to manually ack QoS > 0 messages. Closes #753 & #348. - Improve tests & linters. Modernize build (drop setup.py, use pyproject.toml) +- Fix is_connected property to correctly return False when connection is lost + and loop_start/loop_forever isn't used. Closes #525. + + v1.6.1 - 2021-10-21 =================== diff --git a/src/paho/mqtt/client.py b/src/paho/mqtt/client.py index 024f80ab..1767f603 100644 --- a/src/paho/mqtt/client.py +++ b/src/paho/mqtt/client.py @@ -1290,10 +1290,19 @@ def _loop(self, timeout: float = 1.0) -> MQTTErrorCode: socklist = select.select(rlist, wlist, [], timeout) except TypeError: # Socket isn't correct type, in likelihood connection is lost + # ... or we called disconnect(). In that case the socket will + # be closed but some loop (like loop_forever) will continue to + # call _loop(). We still want to break that loop by returning an + # rc != MQTT_ERR_SUCCESS and we don't want state to change from + # mqtt_cs_disconnecting. + if self._state != ConnectionState.MQTT_CS_DISCONNECTING: + self._state = ConnectionState.MQTT_CS_CONNECTION_LOST return MQTTErrorCode.MQTT_ERR_CONN_LOST except ValueError: # Can occur if we just reconnected but rlist/wlist contain a -1 for # some reason. + if self._state != ConnectionState.MQTT_CS_DISCONNECTING: + self._state = ConnectionState.MQTT_CS_CONNECTION_LOST return MQTTErrorCode.MQTT_ERR_CONN_LOST except Exception: # Note that KeyboardInterrupt, etc. can still terminate since they @@ -1768,6 +1777,8 @@ def loop_misc(self) -> MQTTErrorCode: if self._state == mqtt_cs_disconnecting: rc = MQTTErrorCode.MQTT_ERR_SUCCESS else: + self._state = ConnectionState.MQTT_CS_CONNECTION_LOST + self._easy_log(MQTT_LOG_DEBUG, "... 2") rc = MQTTErrorCode.MQTT_ERR_KEEPALIVE self._do_on_disconnect(rc) @@ -2580,6 +2591,10 @@ def _loop_rc_handle( self._do_on_disconnect(rc, properties) + if rc == MQTT_ERR_CONN_LOST: + self._easy_log(MQTT_LOG_DEBUG, "... 3") + self._state = ConnectionState.MQTT_CS_CONNECTION_LOST + return rc def _packet_read(self) -> MQTTErrorCode: diff --git a/src/paho/mqtt/enums.py b/src/paho/mqtt/enums.py index 33f18cb6..2f167510 100644 --- a/src/paho/mqtt/enums.py +++ b/src/paho/mqtt/enums.py @@ -68,6 +68,7 @@ class ConnectionState(enum.IntEnum): MQTT_CS_CONNECTED = 1 MQTT_CS_DISCONNECTING = 2 MQTT_CS_CONNECT_ASYNC = 3 + MQTT_CS_CONNECTION_LOST = 4 class MessageState(enum.IntEnum):