Using MQTT in .NET: MQTTnet and Mosquitto Implementation
TLDR
- MQTT uses a publish/subscribe pattern, with core roles including Broker, Publisher, Subscriber, and Topic.
- Topics should follow a hierarchical naming convention (e.g.,
home/living-room/temperature), and avoid starting with$(reserved for system use). - QoS levels determine transmission reliability: QoS 0 (at most once), QoS 1 (at least once), QoS 2 (exactly once).
- The actual transmission QoS depends on the minimum value between the Publisher and Subscriber settings.
- When deploying Mosquitto using Docker, ensure
persistenceis configured to retain messages, and handle permissions and account initialization viaentrypoint.sh. - In MQTTnet implementation,
Last Willis only triggered during abnormal disconnections;Retained Messageis suitable for storing the latest state. - For MQTT 5.0 persistent sessions, both
CleanStart = falseandSessionExpiryInterval > 0must be set.
MQTT Basic Concepts and Operation
MQTT (Message Queuing Telemetry Transport) is a lightweight publish/subscribe messaging protocol suitable for IoT device communication.
Core Roles
- Broker: The core of the system, responsible for receiving, filtering, and distributing messages.
- Publisher: The client that publishes messages.
- Subscriber: The client that subscribes to topics to receive messages.
- Topic: A message classification label, with a structure similar to file paths.
Topic Naming Rules and Restrictions
When do naming issues occur: If conventions are not followed when designing topic hierarchies, it can easily lead to subscription failures or permission conflicts.
- Hierarchy Separator: Use
/to separate levels. - Case Sensitivity:
Home/Tempandhome/tempare different topics. - System Topics: Topics starting with
$(e.g.,$SYS/) are reserved for the Broker and should not be used by applications. - Wildcards:
+(single level) and#(multi-level) can only be used for subscriptions, not for publishing.
QoS (Quality of Service)
When do QoS selection difficulties occur: When the system has different tolerances for message loss or duplication, the corresponding QoS level must be selected.
- QoS 0: Highest performance, messages may be lost, suitable for frequently updated sensor data.
- QoS 1: Ensures delivery, but duplicate messages may be received, suitable for control commands.
- QoS 2: Four-way handshake, ensures no loss and no duplication, suitable for financial or billing systems.
Final QoS Calculation Formula: Actual QoS = min(Publish QoS, Subscribe QoS).
Deploying Mosquitto with Docker Compose
When do deployment issues occur: In a containerized environment, if permissions or persistence are not configured correctly, it will lead to data loss after a restart or the inability to write to configuration files.
Key Configuration File (mosquitto.conf)
listener 1883
protocol mqtt
allow_anonymous false
password_file /mosquitto/config/password.txt
persistence true
persistence_location /mosquitto/data/Startup Script (entrypoint.sh)
Must ensure that UID 1883 inside the container has folder permissions:
#!/bin/sh
chown -R 1883:1883 /mosquitto/config /mosquitto/log /mosquitto/data
exec mosquitto -c /mosquitto/config/mosquitto.conf.NET Implementation with MQTTnet
Basic Publish and Subscribe
Example of using MQTTnet to establish a connection and subscribe to a topic:
// Subscription example
var subscribeOptions = new MqttClientSubscribeOptionsBuilder()
.WithTopicFilter(f => f.WithTopic("test/topic").WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce))
.Build();
await client.SubscribeAsync(subscribeOptions);
// Publishing example
var message = new MqttApplicationMessageBuilder()
.WithTopic("test/topic")
.WithPayload("Hello, MQTT!")
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce)
.Build();
await client.PublishAsync(message);Advanced Feature Implementation
Last Will and Testament
When to use: When you need to monitor whether a device has "abnormally disconnected."
- A normal call to
DisconnectAsync()will not trigger the Last Will. - The Broker will only automatically publish the pre-defined Last Will message when the network is interrupted or the program crashes.
Persistent Session
When to use: When you want the client to receive QoS 1/2 messages accumulated during offline periods after reconnecting.
MQTT 5.0 Implementation Recommendation:
var options = new MqttClientOptionsBuilder()
.WithClientId("client-001")
.WithCleanStart(false) // Attempt to use existing Session
.WithSessionExpiryInterval(600) // Retain for 10 minutes after disconnection
.Build();TIP
The complete executable example for this article: CloudyWing/MqttNetMosquittoSample.
Changelog
- Initial document creation.
- Added link to the corresponding GitHub sample project.