-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
recv_timeout should be used as a receive timeout in _sock_exact_recv() #189
Comments
Code to reproduce the issue with (assumes the server behaves according to the MQTT spec and disconnects the client after the keep alive timeout): #!/usr/bin/env python3
import logging
import socket
import ssl
import time
import pytest
import adafruit_minimqtt.adafruit_minimqtt as MQTT
def test_keepalive(keep_alive_timeout):
logging.basicConfig(format='%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
datefmt='%H:%M:%S')
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
host = "localhost"
port = 1883
mqtt_client = MQTT.MQTT(
broker=host,
port=port,
socket_pool=socket,
ssl_context=ssl.create_default_context(),
connect_retries=1,
recv_timeout=5,
keep_alive=keep_alive_timeout,
)
mqtt_client.logger = logger
logger.debug(f"connecting with keep alive = {keep_alive_timeout}")
mqtt_client.connect()
delay = 2 * keep_alive_timeout
logger.debug(f"sleeping for {delay} seconds")
time.sleep(delay)
logger.debug("pinging the server")
try:
mqtt_client.ping()
except MQTT.MMQTTException as e:
logger.error(f"ping failed", exc_info=e)
test_keepalive(16) The output looks like this:
|
I have the same problem and solved it with a workaround/hack. With the hack, the lowest timeout into loop() and not have message dropouts is two seconds (I'm trying to alternate between mqtt polling and reading button presses from an oled). Reply to my issue and I'll provide details. |
@schaefer01 I assume you meant issue #175 ? |
yes, I have a hack that works good enough until there's an official fix. |
socket_timeout
is period which the underlying implementation will break out from a "select" loop, "recv_timeout" should be the maximum period for which to wait for data from the server._sock_exact_recv()
however useskeep_alive
as a receive timeout:Adafruit_CircuitPython_MiniMQTT/adafruit_minimqtt/adafruit_minimqtt.py
Lines 1118 to 1127 in 1c25441
By default
socket_timeout
is 1 second,recv_timeout
is 10 seconds andkeep_alive
is 60 seconds.As a result, when a server disconnects the client and the client pings it, it will take 60 seconds for the client to discover that the connection is unresponsive. Instead,
recv_timeout
should be used. The way I understand it is that keep alive is server side feature and should not trump receive timeout on the client.The fix would simplify the variousNo data ...
MMQTTException
s used throughout the code.The text was updated successfully, but these errors were encountered: