@@ -1034,6 +1034,13 @@ def loop(self, timeout: float = 0) -> Optional[list[int]]:
10341034 :param float timeout: return after this timeout, in seconds.
10351035
10361036 """
1037+ if timeout < self ._socket_timeout :
1038+ raise MMQTTException (
1039+ # pylint: disable=consider-using-f-string
1040+ "loop timeout ({}) must be bigger " .format (timeout )
1041+ + "than socket timeout ({}))" .format (self ._socket_timeout )
1042+ )
1043+
10371044 self ._connected ()
10381045 self .logger .debug (f"waiting for messages for { timeout } seconds" )
10391046
@@ -1065,11 +1072,13 @@ def loop(self, timeout: float = 0) -> Optional[list[int]]:
10651072
10661073 return rcs if rcs else None
10671074
1068- def _wait_for_msg (self ) -> Optional [int ]:
1075+ def _wait_for_msg (self , timeout : Optional [ float ] = None ) -> Optional [int ]:
10691076 # pylint: disable = too-many-return-statements
10701077
10711078 """Reads and processes network events.
10721079 Return the packet type or None if there is nothing to be received.
1080+
1081+ :param float timeout: return after this timeout, in seconds.
10731082 """
10741083 # CPython socket module contains a timeout attribute
10751084 if hasattr (self ._socket_pool , "timeout" ):
@@ -1079,7 +1088,7 @@ def _wait_for_msg(self) -> Optional[int]:
10791088 return None
10801089 else : # socketpool, esp32spi
10811090 try :
1082- res = self ._sock_exact_recv (1 )
1091+ res = self ._sock_exact_recv (1 , timeout = timeout )
10831092 except OSError as error :
10841093 if error .errno in (errno .ETIMEDOUT , errno .EAGAIN ):
10851094 # raised by a socket timeout if 0 bytes were present
@@ -1148,7 +1157,9 @@ def _decode_remaining_length(self) -> int:
11481157 return n
11491158 sh += 7
11501159
1151- def _sock_exact_recv (self , bufsize : int ) -> bytearray :
1160+ def _sock_exact_recv (
1161+ self , bufsize : int , timeout : Optional [float ] = None
1162+ ) -> bytearray :
11521163 """Reads _exact_ number of bytes from the connected socket. Will only return
11531164 bytearray with the exact number of bytes requested.
11541165
@@ -1159,6 +1170,7 @@ def _sock_exact_recv(self, bufsize: int) -> bytearray:
11591170 bytes is returned or trigger a timeout exception.
11601171
11611172 :param int bufsize: number of bytes to receive
1173+ :param float timeout: timeout, in seconds. Defaults to keep_alive
11621174 :return: byte array
11631175 """
11641176 stamp = self .get_monotonic_time ()
@@ -1170,7 +1182,7 @@ def _sock_exact_recv(self, bufsize: int) -> bytearray:
11701182 to_read = bufsize - recv_len
11711183 if to_read < 0 :
11721184 raise MMQTTException (f"negative number of bytes to read: { to_read } " )
1173- read_timeout = self .keep_alive
1185+ read_timeout = timeout if timeout is not None else self .keep_alive
11741186 mv = mv [recv_len :]
11751187 while to_read > 0 :
11761188 recv_len = self ._sock .recv_into (mv , to_read )
0 commit comments