-
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
Maximum topic length #160
Comments
for what its worth.. I have implemented a work around that "works for now"... https://github.com/LelandSindt/analoguEnvoy/blob/8c307e620575397945cd833c15425e1b4d854dbc/circutpythonMQTT/code.py#L71 |
@LelandSindt How long are the topics you are attempting to subscribe to? How many bytes? Could you give me an example of one? There is a topic string length of 65536 bytes imposed by the MQTT specification itself. |
@brentru, Thank you for reaching out. The code included in the initial issue is a working example that connects to This example..
with a total of 123 characters it is certainly shorter than 65k bytes in length. |
@LelandSindt: Thank you for the feedback! I'm unsure if the issue is the topic length or the number of sub-topics. Marking this as a bug until we can formally test this and resolve it. |
In my experimentation and experience it is all about length regardless of number of subtopics. for example subscribing to Please let me known if you need any more specific details. |
Looking at line 1041 (as reported initially in #160 (comment)) in the source code of 1022 def _wait_for_msg(self, timeout: float = 0.1) -> Optional[int]:
1023 # pylint: disable = too-many-return-statements
1024
1025 """Reads and processes network events.
1026 Return the packet type or None if there is nothing to be received.
1027 """
1028 # CPython socket module contains a timeout attribute
1029 if hasattr(self._socket_pool, "timeout"):
1030 try:
1031 res = self._sock_exact_recv(1)
1032 except self._socket_pool.timeout:
1033 return None
1034 else: # socketpool, esp32spi
1035 try:
1036 res = self._sock_exact_recv(1)
1037 except OSError as error:
1038 if error.errno in (errno.ETIMEDOUT, errno.EAGAIN):
1039 # raised by a socket timeout if 0 bytes were present
1040 return None
1041 raise MMQTTException from error |
Trying this with CPython and the latest gratest MiniMQTT (926846c), I too get an exception:
Yes, the broker hung up on the client after seeing the subscribe request. The code to reproduce this is trivial: #!/usr/bin/env python3
import json
import socket
import ssl
import sys
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import logging
def main():
"""
Demonstrate how to use MQTT log handler.
"""
logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.info("Creating MQTT instance")
broker = "172.40.0.3"
port = 1883
mqtt_client = MQTT.MQTT(
broker=broker,
port=port,
socket_pool=socket,
ssl_context=ssl.create_default_context(),
connect_retries=3,
)
mqtt_client.enable_logger(logging, log_level=logging.DEBUG)
logger.info("Connecting to MQTT broker")
mqtt_client.connect()
topics = [("broken/path/path/path/path/path/path/path/path/path/path/path/path/path/path/path/path/path/path/path/path/path/pat/toolong",0)]
logger.info(f"subscribing to {topics}")
mqtt_client.subscribe(topics) The broker in question is Mosquitto. Upon reception of the MQTT packet, the server reports this in the log:
and looking at the traffic dump with Wireshark, the MQTT protocol dissector seems to agree that the SUBSCRIBE packet was malformed. |
The problem is in the remaining length bytes. In this case the length is 130 in decimal which is 0x80 hexadecimal, however according to the encoding scheme (MQTT 3.1.1 section 2.2.3 Remaining Length) if the top level bit is set (which it is for 0x80), the next byte contains continuation. The Adafruit_CircuitPython_MiniMQTT/adafruit_minimqtt/adafruit_minimqtt.py Lines 815 to 819 in 926846c
|
Made time to update and test today... working as expected, thank you! |
I am working with Adafruit CircuitPython 8.0.4 on 2023-03-15; Raspberry Pi Pico W with rp2040, Board ID:raspberry_pi_pico_w. Library version adafruit-circuitpython-bundle-8.x-mpy-20230315.
When I try to subscribe to multiple "long" or a single "very long" topic I get the following error(s)
Here is the code I am running...
I have not been able to find any topic length limits in the documentation. Is this behaviour expected?
The text was updated successfully, but these errors were encountered: