diff --git a/ChangeLog.txt b/ChangeLog.txt index c86f40c4..2badc30f 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -5,6 +5,9 @@ v2.0.0 - 2023-xx-xx Minimum tested version is Python 3.7 - Add on_pre_connect() callback, which is called immediately before a connection attempt is made. +- 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 c792ca3f..97c2f264 100644 --- a/src/paho/mqtt/client.py +++ b/src/paho/mqtt/client.py @@ -118,6 +118,7 @@ mqtt_cs_connected = 1 mqtt_cs_disconnecting = 2 mqtt_cs_connect_async = 3 +mqtt_cs_connection_lost = 4 # Message state mqtt_ms_invalid = 0 @@ -600,7 +601,8 @@ def __init__(self, client_id="", clean_session=None, userdata=None, self._ssl_context = None # Only used when SSL context does not have check_hostname attribute self._tls_insecure = False - self._logger = None + logging.basicConfig(level=logging.DEBUG) + self._logger = logging.getLogger("plop") self._registered_write = False # No default callbacks self._on_log = None @@ -1153,10 +1155,19 @@ def _loop(self, timeout=1.0): 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 != mqtt_cs_disconnecting: + self._state = mqtt_cs_connection_lost return MQTT_ERR_CONN_LOST except ValueError: # Can occur if we just reconnected but rlist/wlist contain a -1 for # some reason. + if self._state != mqtt_cs_disconnecting: + self._state = mqtt_cs_connection_lost return MQTT_ERR_CONN_LOST except Exception: # Note that KeyboardInterrupt, etc. can still terminate since they @@ -1620,6 +1631,8 @@ def loop_misc(self): if self._state == mqtt_cs_disconnecting: rc = MQTT_ERR_SUCCESS else: + self._state = mqtt_cs_connection_lost + self._easy_log(MQTT_LOG_DEBUG, "... 2") rc = MQTT_ERR_KEEPALIVE self._do_on_disconnect(rc) @@ -2389,6 +2402,10 @@ def _loop_rc_handle(self, rc, properties=None): self._do_on_disconnect(rc, properties) + if rc == MQTT_ERR_CONN_LOST: + self._easy_log(MQTT_LOG_DEBUG, "... 3") + self._state = mqtt_cs_connection_lost + return rc def _packet_read(self):