-
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
improve ping handling #199
Conversation
- do not send PINGREQ unnecessarily - send PINGREQ even on long loop timeouts fixes adafruit#198
Tested on my trusty #!/usr/bin/env python3
"""
test for https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/pull/199
"""
import ssl
import time
import wifi
import socketpool
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import adafruit_logging as logging
from secrets import secrets
def main():
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.info(f"Connecting to wifi {secrets['SSID']}")
wifi.radio.connect(secrets["SSID"], secrets["password"], timeout=20)
logger.info(f"Connected to {secrets['SSID']}")
logger.debug(f"IP: {wifi.radio.ipv4_address}")
pool = socketpool.SocketPool(wifi.radio)
keep_alive_timeout = 8
host = "172.40.0.3"
port = 1883
mqtt_client = MQTT.MQTT(
broker=host,
port=port,
socket_pool=pool,
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()
# Subscribe to something with traffic to be more real. No on_message, tho.
mqtt_client.subscribe("#")
logger.info("### loop() with egress MQTT message traffic")
# No PINGREQ should be sent during this cycle.
rcs_test = []
num_iter = 8 * keep_alive_timeout
for i in range(1, num_iter):
logger.debug(f"iteration #{i}/{num_iter - 1}")
mqtt_client.publish("foo", "bar")
rcs = mqtt_client.loop(1)
rcs_test.extend(rcs)
logger.info(f"rcs = {rcs_test}")
assert 208 not in rcs_test
# Give the user some time to digest the test result.
logger.info("### sleeping for 10 seconds")
time.sleep(10)
logger.info("### loop() with no egress message traffic and long timeout")
# Multiple PINGREQs should be sent during this cycle.
delay = 2 * keep_alive_timeout
rcs_test = []
for _ in range(3):
logger.debug(f"calling loop({delay})")
try:
rcs = mqtt_client.loop(delay)
rcs_test.extend(rcs)
logger.info(f"Got message types: {rcs}")
except MQTT.MMQTTException as e:
logger.error(f"failed: {e}")
logger.info(f"rcs = {rcs_test}")
assert 208 in rcs_test
if __name__ == "__main__":
main() the output looked like this:
|
# Conflicts: # adafruit_minimqtt/adafruit_minimqtt.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me.
I merged main and resolved the conflicts.
I tried testing with the given test and did get it to run part way but I think the second half of it doesn't work with adafruit.io in the same way as your test broker. on AIO I hit rate limits that the front end warned me about and the PINGRESP was not sent as the script expected.
I did test basic MQTT functionality seperately and both receiving and sending data appears to be working successfully.
My testing was on a feather TFT ESP32-S3
Updating https://github.com/adafruit/Adafruit_CircuitPython_Wiznet5k to 5.0.6 from 5.0.5: > Merge pull request adafruit/Adafruit_CircuitPython_Wiznet5k#125 from FoamyGuy/recv_timeout Updating https://github.com/adafruit/Adafruit_CircuitPython_HTTPServer to 4.5.1 from 4.5.0: > Merge pull request adafruit/Adafruit_CircuitPython_HTTPServer#76 from michalpokusa/routes-refactor Updating https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT to 7.5.8 from 7.5.6: > Merge pull request adafruit/Adafruit_CircuitPython_MiniMQTT#199 from vladak/loop_vs_keep_alive > Merge pull request adafruit/Adafruit_CircuitPython_MiniMQTT#200 from vladak/loop_timeout_vs_socket_timeout > Merge pull request adafruit/Adafruit_CircuitPython_MiniMQTT#184 from rjauquet/rej-fix-loop-blocking Updating https://github.com/adafruit/Adafruit_CircuitPython_PIOASM to 1.0.0 from 0.8.2: > Merge pull request adafruit/Adafruit_CircuitPython_PIOASM#61 from Gebhartj/Gebhartj-patch-1 Updating https://github.com/adafruit/Adafruit_CircuitPython_Bundle/circuitpython_library_list.md to NA from NA: > Updated download stats for the libraries
This changes the way how pings are treated. Rather than sending PINGREQ based on how
loop()
is called, it is based on how messages are sent to the broker (in accordance with the MQTT spec). Also, the ping handling was folded into the loop inloop()
to make it work in cases with loop timeouts longer than the keep alive timeout.I plan to test this on a QtPy.