Skip to content

Commit d478cca

Browse files
committed
avoid endless loop when waiting for data from broker
fixes #115
1 parent 68cf825 commit d478cca

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

adafruit_minimqtt/adafruit_minimqtt.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class MQTT:
128128
:param str client_id: Optional client identifier, defaults to a unique, generated string.
129129
:param bool is_ssl: Sets a secure or insecure connection with the broker.
130130
:param int keep_alive: KeepAlive interval between the broker and the MiniMQTT client.
131+
:param int recv_timeout: receive timeout, in seconds.
131132
:param socket socket_pool: A pool of socket resources available for the given radio.
132133
:param ssl_context: SSL context for long-lived SSL connections.
133134
:param bool use_binary_mode: Messages are passed as bytearray instead of string to callbacks.
@@ -146,6 +147,7 @@ def __init__(
146147
client_id=None,
147148
is_ssl=True,
148149
keep_alive=60,
150+
recv_timeout=10,
149151
socket_pool=None,
150152
ssl_context=None,
151153
use_binary_mode=False,
@@ -160,6 +162,7 @@ def __init__(
160162
self._socket_timeout = socket_timeout
161163

162164
self.keep_alive = keep_alive
165+
self._recv_timeout = recv_timeout
163166
self._user_data = None
164167
self._is_connected = False
165168
self._msg_size_lim = MQTT_MSG_SZ_LIM
@@ -522,6 +525,7 @@ def connect(self, clean_session=True, host=None, port=None, keep_alive=None):
522525
self._send_str(self._password)
523526
if self.logger is not None:
524527
self.logger.debug("Receiving CONNACK packet from broker")
528+
stamp = time.monotonic()
525529
while True:
526530
op = self._wait_for_msg()
527531
if op == 32:
@@ -535,6 +539,12 @@ def connect(self, clean_session=True, host=None, port=None, keep_alive=None):
535539
self.on_connect(self, self._user_data, result, rc[2])
536540
return result
537541

542+
if op is None:
543+
if time.monotonic() - stamp > self._recv_timeout:
544+
raise MMQTTException(
545+
f"No data received from broker for {self._recv_timeout} seconds."
546+
)
547+
538548
def disconnect(self):
539549
"""Disconnects the MiniMQTT client from the MQTT broker."""
540550
self.is_connected()
@@ -645,6 +655,7 @@ def publish(self, topic, msg, retain=False, qos=0):
645655
if qos == 0 and self.on_publish is not None:
646656
self.on_publish(self, self._user_data, topic, self._pid)
647657
if qos == 1:
658+
stamp = time.monotonic()
648659
while True:
649660
op = self._wait_for_msg()
650661
if op == 0x40:
@@ -657,6 +668,12 @@ def publish(self, topic, msg, retain=False, qos=0):
657668
self.on_publish(self, self._user_data, topic, rcv_pid)
658669
return
659670

671+
if op is None:
672+
if time.monotonic() - stamp > self._recv_timeout:
673+
raise MMQTTException(
674+
f"No data received from broker for {self._recv_timeout} seconds."
675+
)
676+
660677
def subscribe(self, topic, qos=0):
661678
"""Subscribes to a topic on the MQTT Broker.
662679
This method can subscribe to one topics or multiple topics.
@@ -705,6 +722,7 @@ def subscribe(self, topic, qos=0):
705722
for t, q in topics:
706723
self.logger.debug("SUBSCRIBING to topic %s with QoS %d", t, q)
707724
self._sock.send(packet)
725+
stamp = time.monotonic()
708726
while True:
709727
op = self._wait_for_msg()
710728
if op == 0x90:
@@ -718,6 +736,12 @@ def subscribe(self, topic, qos=0):
718736
self._subscribed_topics.append(t)
719737
return
720738

739+
if op is None:
740+
if time.monotonic() - stamp > self._recv_timeout:
741+
raise MMQTTException(
742+
f"No data received from broker for {self._recv_timeout} seconds."
743+
)
744+
721745
def unsubscribe(self, topic):
722746
"""Unsubscribes from a MQTT topic.
723747
@@ -755,6 +779,7 @@ def unsubscribe(self, topic):
755779
if self.logger is not None:
756780
self.logger.debug("Waiting for UNSUBACK...")
757781
while True:
782+
stamp = time.monotonic()
758783
op = self._wait_for_msg()
759784
if op == 176:
760785
rc = self._sock_exact_recv(3)
@@ -767,6 +792,12 @@ def unsubscribe(self, topic):
767792
self._subscribed_topics.remove(t)
768793
return
769794

795+
if op is None:
796+
if time.monotonic() - stamp > self._recv_timeout:
797+
raise MMQTTException(
798+
f"No data received from broker for {self._recv_timeout} seconds."
799+
)
800+
770801
def reconnect(self, resub_topics=True):
771802
"""Attempts to reconnect to the MQTT broker.
772803

0 commit comments

Comments
 (0)