-
Notifications
You must be signed in to change notification settings - Fork 41
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
multiple retained messages for the same topic #86
Comments
Hello I've modified the unit test on retained messages... Unable to reproduce this. The test added is there 30e75b8 Either you do not use the main branch, or .... the map is buggy on ESP implementation. |
Also this gave me the opportunity to add a test for the payload truncated message !!! |
The std::map seems not to recognise any values unless I use hardcoded quoted strings. |
The commit for the test added is there (30e75b8) |
Yes, this sounds very strange. |
Are you using the new 2.0.x environment? I had compiled it for RP2040 and ESP8266, both behave the same. |
No. Unit test are not running on the ESP, but on Linux. This is why I suspect the map to be responsible of this :-( |
I can confirm the multiple messages for one topic with my ESP32 on the latest version of this library. Last 16 publishes from my client with retain always set to true: After resetting my client and resubscribing to the topics I get the following output: However, I've lost the last value for the thermostat/set_temp topic because of the behavior. I would expect only the last value for each topic to be retained. I would also expect a topic to be completely removed from the buffer only if there are more than 10 topics that are trying to retain values. |
Trying to debug this because it's the last piece of code I need to make my system work. Digging further, Topic is a subclass of IndexedString and its == operator is looking at the index value. By making index public I probed it while sending multiple publish with retain requests and it keeps incrementing. So the same string is getting different indexes... It also seems that the client subscription list uses Topic.matches() which will try to use indexes for quick matches but will fallback to the strings. So that's why the clients are still receiving topics they are subscribed too even though the indexes keep changing. So a big problem is happening in StringIndexer.h strToIndex(). The real problem maybe happening at a higher level but I am not ever entering the following if statement. So for the same topic, I'm never getting the same indexed string, so the map for retained can't == to previous topics. So I think the fundamental problem is line 77 in StringIndexer.h. Now to go back and check functionality. Looks like that did it! |
TinyMqtt.cpp, line 965:
auto old = retained.find(topic);
does not work as expected. Consequentially I get multiple retained messages for the same topic.
Arduino 2.1.0
Also Retain seems to store the whole Publish message instead of just the message string, which is quite a bit of overkill (memory consuming) at long topics. In accordance to HiveMQ (https://www.hivemq.com/blog/mqtt-essentials-part-8-retained-messages/) it should just be the QOS and the message string itself.
Would it not be better to just store a reference to the topic?
Then duplicates would be far less likely to occur by design and the load on the memory would be lesser. Also the handling of empty messages (delete/ignore) would be much easier.
To replicate the issue, initialise MqttBroker with a value >1 for retained values and send multiple retained messages to the same topic. Connect a client and subscribe to the topic. Now you should see all retained messages popping up, instead of just one.
I have traced the error to the aforementioned line and a debug output there reveals that [topic] is never found. Using a quoted string as argument on the other side does return a found result.
The text was updated successfully, but these errors were encountered: