Introduction: This article is based on practical experience, and for foundational concepts like MQTT, it is recommended to search online for more information.
Recommended Resources:mica-mqtt documentation
1. Brief Introduction to MQTT
As a mainstream protocol in today’s Internet of Things (IoT), MQTT has a wide range of applications. If you want to understand or even work in the IoT industry, MQTT is unavoidable.
1.1 clientId
As the name suggests, <span>clientId</span> is the <span>ID</span> of the client, which the server can use to identify the corresponding device.
The ID implies uniqueness, so please ensure the uniqueness of the clientId when defining it. If duplicated, it may lead to situations where two devices kick each other offline.
- 1. Uniqueness: Ensure the uniqueness of the clientId for unique identification of devices;
- 2. Length Limit: Different MQTT implementations generally have length limits, with some allowing 23 characters and others 64 characters. Therefore, it is recommended not to exceed
<span>20</span>characters. - 3. Avoid Special Characters: This is something everyone understands; being too unique can lead to strange issues. It is best to use
<span>uppercase and lowercase letters</span>,<span>numbers</span>,<span>_</span>, and<span>-</span>, these four types are sufficient, and have been tested without issues.
1.2 Topic
The Topic is a very important concept in MQTT, serving as a classification label for messages. Clients interact by subscribing to or publishing specific topics. You can simply understand it as the API interface in our code (the one written in the controller), which is separated by slashes <span>/</span>. Of course, if you are a user of message queues like Kafka, you should be familiar with the concept of Topic. Here’s an example.
| Name | Topic Address |
|---|---|
| Real-time Data | /mqtt/xxx/xxx/live |
| Historical Data | /mqtt/xxx/xxx/history |
| Alarm Events | /mqtt/xxx/xxx/event |
| Control Commands | /cloud/xxx/xxx/switch |
The two layers of xxx in the middle generally represent the device’s identification information. 👆 The above is just an example of the Topic format, not all MQTT devices have these Topics.
1.2.1 Topic Application Scenarios
- 1. Real-time Monitoring: By subscribing to relevant Topics, real-time device status and data can be received, enabling real-time monitoring of devices;
- 2. Remote Control: By publishing commands to specific Topics, control and operation of remote devices can be achieved;
- 3. Alarm Notifications: When a device detects an abnormal situation, it can publish an alarm message to a designated Topic to promptly notify relevant personnel or systems;
- 4. Data Collection: By subscribing to data Topics, data from multiple devices can be collected and processed centrally.
1.2.2 Topic Naming Conventions
The following information is mainly based on standard gateways and is not a strict requirement.
Generally, standard Topic formats have the following characteristics:
- 1. Unified Prefix: The first layer usually indicates the direction of transmission, as in the examples in the table above. Topics starting with
<span>/mqtt</span>indicate devices reporting to the server, while those starting with<span>/cloud</span>indicate commands sent from the server to control devices; - 2. Unified Suffix: The last layer usually indicates the direction of transmission, as in the examples in the table above. Topics ending with
<span>/live</span>indicate devices reporting real-time data, while those ending with<span>/history</span>indicate devices reporting historical data; - 3. Includes Device Identification: The middle part of the Topic generally includes the gateway’s pkey, sn, or clientId.
Of course, we can customize Topics in the MQTT service, and the format can be based on personal preferences. However, it is hoped that everyone defines a Topic for each function, rather than using fields like <span>type</span> in the message body to differentiate.
1.2.3 Topic Wildcards
Using the table above as an example, the middle of the Topic usually contains the device identification or clientId, and it is impractical to write a subscription for each device; wildcards are generally used. For example, the Topic <span>/mqtt/xxx/xxx/live</span> can be demonstrated with two types of wildcards.
- 1. Multi-layer Matching
<span>#</span>:<span>#</span>can match multiple layers, for example: we can use<span>/mqtt/#/live</span>to represent the above example; - 2. Single-layer Matching
<span>+</span>:<span>+</span>can match a single layer, for example: we can use<span>/mqtt/+/+/live</span>to represent the above example.
1.2.4 Topic Shared Subscriptions
This feature is generally useful when the server distributes data. It will be introduced in a separate article later, so use it cautiously if you are not familiar with it.
Generally, if multiple clients subscribe to the same Topic, all clients will receive messages from that Topic. However, sometimes we only want one client to receive the data. For example, when the data volume is very large, we may want to use multiple clients to share the load, which requires shared subscriptions. In simple terms, shared subscriptions are similar to Nginx load balancing, where the server randomly distributes data to one client.
1.2.4.1 Single Group Shared Subscription
To subscribe to a Topic, add the prefix <span>$queue/</span> (note the trailing <span>/</span>), when multiple clients subscribe to the Topic <span>$queue/xxx</span>, if the publisher publishes to Topic <span>xxx</span>, only one client will receive the message.
1.2.4.2 Group Shared Subscription
To subscribe to a Topic, add the prefix <span>$share/<group>/</span> (note the trailing <span>/</span>, where <span><group></span> represents the group and can be any character), when clients subscribe to Topics <span>$share/aaa/xxx</span> and <span>$share/bbb/xxx</span>, if the publisher publishes to Topic <span>xxx</span>, only one client in each group will receive the message.
<span>It is important to note the trailing / in the shared subscription prefix. If your Topic starts with /, it will result in two /, for example, if the Topic is /mqtt/xxx/xxx/live, the shared subscription Topic will be $queue//mqtt/xxx/xxx/live, which looks strange. Therefore, for custom shared subscriptions, I usually do not start with /. Please pay attention ⚠️!!!!!!!!!!</span>
1.3 QoS
This is quite important, but in IoT, we generally do not need to set it separately. You can refer to the <span>mica-mqtt</span> documentation for more information:mica-mqtt
1.4 Message Body
The messages transmitted by MQTT are generally received as byte arrays <span>byte[]</span>, which can be converted to strings to obtain the actual information.
2. Common Tools for MQTT
I initially planned to write a separate article on tool usage, but I found two existing articles that are simple enough to refer to.
Reference Blogs:Reference 1Reference 2
2.1 EMQX
Theoretically, EMQX is not just a tool; it is a platform or system. There is an open-source version, as well as more robust cloud and enterprise versions, but for most small to medium IoT platforms, the open-source version is sufficient.EMQX documentation link:EMQX Documentation
Although EMQX is well-known and widely used, it is strongly recommended not to expose EMQX as a data receiving service on the public network, as it may affect the entire platform due to potential vulnerabilities in EMQX.
2.2 MQTTX
File shared via cloud storage: emqx-5.3.2-windows-amd64.zip Link: https://pan.baidu.com/s/1BYmqQQaPHkshyf-vkFK5Sw?pwd=hpua Extraction Code: hpua — Shared by Baidu Cloud Super Member v9