This program can handle multiple clients, but currently can only handle one topic mapping per client. I think it may be possible in the future to handle multiple mappings per client, but I haven't delved too far into it yet. The program connects to only one broker.
This was deveoped using Qt 5.14.2 using Qt Creator 4.12.3 on Fedora 31 and openSUSE Tumbleweed. Algorithms and data structures were developed in KDevelop 5.5.2 using GCC 9.3.1 and then converted into Qt. The program generally passes most MQTT messages to a broker and only intercepts those that deal with topic names. If a mapping has been defined for a client, the program will apply diff to all incoming and outgoing topics and rewrite parts of the MQTT message that deal with topic names. It will keep all QoS, Will, and Duplicate settings.There are several examples of how diff.cpp works and is applied, but the TLDR is this: a topic name needs patterns that identify parts of the topic that are to be extracted and either re-mapped in new positions or taken out completely. It is a specialized
Here are some different examples than those in diff.cpp:
- stringWithMapping: this/is/a/{0}-{1}/{2}, stringMapAgainst: this/is/a/bad-topic/reallybad, stringNewMapping: this/{0}/{2}: This will create the new topic this/bad/reallybad
- stringWithMapping:new/CAP1thereCAP2, stringMapAgainst:new/hellotheremaam, stringNewMapping: CAP1/CAP2: This will create the new topic: hello/maam
- stringWithMapping:device/uglytopic/{0}, stringMapAgainst:uglytopic/PIT301, stringNewMapping: device/{0}: This inadvertently turns "device" in a capture group since it doesn't exactly match anything in stringMapAgainst. Thus the resulting new topic is just "PIT301."
There are dozens of ways to implement a trie in C++. This approach is similar to one that I have taken previously in Python. Although there are Python packages for tries, a topic trie is very specialized in that it must deal with wildcards, so you're left having to implement a custom trie yourself. A very easy and straight-forward approach in Python is to make a trie out of nested dictionaries. Here in Qt we use an unordered_map. We could have just as easily used a QHash.
Because the program maps all incoming publish and subscribe topics, if you need wildcard in a subscription it would be best to include in the mapping definitions, namely in the remap topic rule. In the future I plan to have diff disregard topic fragments that contain '*' or '#.' It will probably apply diff to each topic fragment, i.e. each string between forward slashes.
Setup for screenshosts: MQTTX and Node-RED clients connect to MQTTMockingbird. Used mosquitto broker to test incoming and subscribe messages. Mosquitto was set to verbose mode to check that topics were getting mapped.
 Shows mappings for MQTTX and Node-RED clients.
Subclass QWidget to make custom widget show up in QListWidget.
Show incoming topic mapped to a new topic.
Check mosquitto that the topic was mapped.
Subscribe from MQTTX subscribed to "this/is/a/igetreplaced," but the incoming topic is mapped back to "this/is/a/igetreplaced@bad/badtopic."