@@ -128,6 +128,7 @@ class MQTT:
128
128
:param str client_id: Optional client identifier, defaults to a unique, generated string.
129
129
:param bool is_ssl: Sets a secure or insecure connection with the broker.
130
130
:param int keep_alive: KeepAlive interval between the broker and the MiniMQTT client.
131
+ :param int recv_timeout: receive timeout, in seconds.
131
132
:param socket socket_pool: A pool of socket resources available for the given radio.
132
133
:param ssl_context: SSL context for long-lived SSL connections.
133
134
:param bool use_binary_mode: Messages are passed as bytearray instead of string to callbacks.
@@ -146,6 +147,7 @@ def __init__(
146
147
client_id = None ,
147
148
is_ssl = True ,
148
149
keep_alive = 60 ,
150
+ recv_timeout = 10 ,
149
151
socket_pool = None ,
150
152
ssl_context = None ,
151
153
use_binary_mode = False ,
@@ -157,7 +159,13 @@ def __init__(
157
159
self ._sock = None
158
160
self ._backwards_compatible_sock = False
159
161
self ._use_binary_mode = use_binary_mode
162
+
163
+ if recv_timeout <= socket_timeout :
164
+ raise MMQTTException (
165
+ "recv_timeout must be strictly greater than socket_timeout"
166
+ )
160
167
self ._socket_timeout = socket_timeout
168
+ self ._recv_timeout = recv_timeout
161
169
162
170
self .keep_alive = keep_alive
163
171
self ._user_data = None
@@ -522,6 +530,7 @@ def connect(self, clean_session=True, host=None, port=None, keep_alive=None):
522
530
self ._send_str (self ._password )
523
531
if self .logger is not None :
524
532
self .logger .debug ("Receiving CONNACK packet from broker" )
533
+ stamp = time .monotonic ()
525
534
while True :
526
535
op = self ._wait_for_msg ()
527
536
if op == 32 :
@@ -535,6 +544,12 @@ def connect(self, clean_session=True, host=None, port=None, keep_alive=None):
535
544
self .on_connect (self , self ._user_data , result , rc [2 ])
536
545
return result
537
546
547
+ if op is None :
548
+ if time .monotonic () - stamp > self ._recv_timeout :
549
+ raise MMQTTException (
550
+ f"No data received from broker for { self ._recv_timeout } seconds."
551
+ )
552
+
538
553
def disconnect (self ):
539
554
"""Disconnects the MiniMQTT client from the MQTT broker."""
540
555
self .is_connected ()
@@ -645,6 +660,7 @@ def publish(self, topic, msg, retain=False, qos=0):
645
660
if qos == 0 and self .on_publish is not None :
646
661
self .on_publish (self , self ._user_data , topic , self ._pid )
647
662
if qos == 1 :
663
+ stamp = time .monotonic ()
648
664
while True :
649
665
op = self ._wait_for_msg ()
650
666
if op == 0x40 :
@@ -657,6 +673,12 @@ def publish(self, topic, msg, retain=False, qos=0):
657
673
self .on_publish (self , self ._user_data , topic , rcv_pid )
658
674
return
659
675
676
+ if op is None :
677
+ if time .monotonic () - stamp > self ._recv_timeout :
678
+ raise MMQTTException (
679
+ f"No data received from broker for { self ._recv_timeout } seconds."
680
+ )
681
+
660
682
def subscribe (self , topic , qos = 0 ):
661
683
"""Subscribes to a topic on the MQTT Broker.
662
684
This method can subscribe to one topics or multiple topics.
@@ -705,6 +727,7 @@ def subscribe(self, topic, qos=0):
705
727
for t , q in topics :
706
728
self .logger .debug ("SUBSCRIBING to topic %s with QoS %d" , t , q )
707
729
self ._sock .send (packet )
730
+ stamp = time .monotonic ()
708
731
while True :
709
732
op = self ._wait_for_msg ()
710
733
if op == 0x90 :
@@ -718,6 +741,12 @@ def subscribe(self, topic, qos=0):
718
741
self ._subscribed_topics .append (t )
719
742
return
720
743
744
+ if op is None :
745
+ if time .monotonic () - stamp > self ._recv_timeout :
746
+ raise MMQTTException (
747
+ f"No data received from broker for { self ._recv_timeout } seconds."
748
+ )
749
+
721
750
def unsubscribe (self , topic ):
722
751
"""Unsubscribes from a MQTT topic.
723
752
@@ -755,6 +784,7 @@ def unsubscribe(self, topic):
755
784
if self .logger is not None :
756
785
self .logger .debug ("Waiting for UNSUBACK..." )
757
786
while True :
787
+ stamp = time .monotonic ()
758
788
op = self ._wait_for_msg ()
759
789
if op == 176 :
760
790
rc = self ._sock_exact_recv (3 )
@@ -767,6 +797,12 @@ def unsubscribe(self, topic):
767
797
self ._subscribed_topics .remove (t )
768
798
return
769
799
800
+ if op is None :
801
+ if time .monotonic () - stamp > self ._recv_timeout :
802
+ raise MMQTTException (
803
+ f"No data received from broker for { self ._recv_timeout } seconds."
804
+ )
805
+
770
806
def reconnect (self , resub_topics = True ):
771
807
"""Attempts to reconnect to the MQTT broker.
772
808
0 commit comments