Chd.Library.MQTT
8.7.0
dotnet add package Chd.Library.MQTT --version 8.7.0
NuGet\Install-Package Chd.Library.MQTT -Version 8.7.0
<PackageReference Include="Chd.Library.MQTT" Version="8.7.0" />
<PackageVersion Include="Chd.Library.MQTT" Version="8.7.0" />
<PackageReference Include="Chd.Library.MQTT" />
paket add Chd.Library.MQTT --version 8.7.0
#r "nuget: Chd.Library.MQTT, 8.7.0"
#:package Chd.Library.MQTT@8.7.0
#addin nuget:?package=Chd.Library.MQTT&version=8.7.0
#tool nuget:?package=Chd.Library.MQTT&version=8.7.0
Library.MQTT 📡
Library.MQTT is a lightweight MQTT client and server library for .NET 8 applications. Perfect for IoT devices, real-time messaging, and pub/sub architectures. Built on MQTTnet with simplified configuration and automatic service registration.
What Does It Do?
Library.MQTT provides production-ready MQTT infrastructure:
- MQTT Server: Host your own MQTT broker in ASP.NET Core apps
- MQTT Client: Subscribe to topics and handle messages with simple callbacks
- Auto Configuration: Load MQTT settings from
appsettings.json - Hosted Services: Background services for continuous server/client operation
- Topic-Based Routing: Subscribe to specific topics with custom handlers
- Easy Testing: Test with MQTT Box or any MQTT client tool
Who Is It For?
- IoT Developers building device-to-cloud communication
- Real-Time Apps needing lightweight pub/sub messaging
- Microservices using event-driven architecture
- Home Automation projects with MQTT-enabled devices
- Telemetry Systems collecting sensor data from edge devices
📚 Table of Contents
- Why Library.MQTT?
- Installation
- Quick Start Guide
- Configuration Reference
- Real-World Examples
- API Reference
- Troubleshooting
- Best Practices
- FAQ
- Related CHD Packages
Stop Reinventing MQTT Setup! ⏰
Every IoT project needs MQTT. Stop configuring MQTTnet brokers manually. Library.MQTT gives you production-ready MQTT in 5 lines.
The Problem 😫
// ❌ Manual MQTT setup (50+ lines per project):
var mqttFactory = new MqttFactory();
var mqttServerOptions = new MqttServerOptionsBuilder()
.WithDefaultEndpoint()
.WithDefaultEndpointPort(1883)
.WithConnectionValidator(context => { /* validation */ })
.Build();
var mqttServer = mqttFactory.CreateMqttServer(mqttServerOptions);
await mqttServer.StartAsync();
var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("localhost", 1883)
.WithCredentials("username", "password")
.Build();
await mqttClient.ConnectAsync(mqttClientOptions);
// ... plus message handlers, reconnection logic, hosted services...
The Solution ✅
// ✅ One line MQTT server + client
builder.Services.AddMQTTServer<MyMessageHandler, MQTTServerServiceBase>("temperature");
// ✅ Custom message handler
public class MyMessageHandler : MQTTClientServiceBase
{
public override void OnMessageReceived(string message)
{
Console.WriteLine($"Temperature: {message}°C");
}
}
Why Library.MQTT?
| Problem | Without Library.MQTT | With Library.MQTT |
|---|---|---|
| Server Setup | 50+ lines of MQTTnet configuration | 1 line: .AddMQTTServer<T>() |
| Client Setup | Manual connection, options, credentials | Auto-configured from appsettings.json |
| Message Handling | Custom event handlers, delegates | Override OnMessageReceived() |
| Background Services | Manual IHostedService implementation |
Built-in hosted services |
| Configuration | Hardcoded or manual config reading | appsettings.json auto-loading |
| Reconnection | Manual retry logic | Built-in with MQTTnet.Extensions |
Key Benefits:
- ⚡ 90% less code - No MQTT boilerplate
- 📡 Production-ready - Based on MQTTnet 4.3.3
- 🎨 Clean APIs - Inherit
MQTTClientServiceBasefor custom logic - 🔧 Flexible - Supports both server and client in same app
- 📚 Well-tested - Used in CHD IoT projects
- 🚀 Easy debugging - Test with MQTT Box or any MQTT client
Installation
dotnet add package Library.MQTT
NuGet Package Manager:
Install-Package Library.MQTT
Package Reference (.csproj):
<PackageReference Include="Library.MQTT" Version="8.5.6" />
Quick Start Guide
1️⃣ MQTT Server + Client Setup
Step 1: Add Configuration
// appsettings.json
{
"MQTT": {
"UserName": "iot_device",
"Password": "secure_password",
"Host": "localhost",
"Port": "1883"
}
}
Step 2: Create Message Handler
public class TemperatureHandler : MQTTClientServiceBase
{
private readonly ILogger<TemperatureHandler> _logger;
public TemperatureHandler(string topic, ILogger<TemperatureHandler> logger)
: base(topic)
{
_logger = logger;
}
// ✅ Override to handle incoming messages
public override void OnMessageReceived(string message)
{
_logger.LogInformation($"Temperature received: {message}°C");
// Parse and process message
if (double.TryParse(message, out double temp))
{
if (temp > 30)
_logger.LogWarning("High temperature alert!");
}
}
}
Step 3: Register Services
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// ✅ Register MQTT server + client with one line
builder.Services.AddMQTTServer<TemperatureHandler, MQTTServerServiceBase>("temperature");
var app = builder.Build();
app.Run();
That's it! Your app now:
- ✅ Hosts an MQTT broker on port 1883
- ✅ Subscribes to
temperaturetopic - ✅ Handles messages in
TemperatureHandler
2️⃣ Custom Message Handler
Handle multiple topics:
public class SensorHandler : MQTTClientServiceBase
{
private readonly IHubContext<SensorHub> _hub; // SignalR for real-time UI
public SensorHandler(string topic, IHubContext<SensorHub> hub)
: base(topic)
{
_hub = hub;
}
public override void OnMessageReceived(string message)
{
// Parse JSON payload
var data = JsonSerializer.Deserialize<SensorData>(message);
// Store in database
_db.SensorReadings.Add(new SensorReading
{
DeviceId = data.DeviceId,
Value = data.Value,
Timestamp = DateTime.UtcNow
});
_db.SaveChanges();
// Push to web dashboard via SignalR
_hub.Clients.All.SendAsync("SensorUpdate", data);
}
}
public class SensorData
{
public string DeviceId { get; set; }
public double Value { get; set; }
public string Unit { get; set; }
}
3️⃣ Testing with MQTT Box
Download: MQTT Box or use MQTT Explorer
Connection Settings:
- Protocol: mqtt/tcp
- Host: localhost
- Port: 1883
- Username: iot_device
- Password: secure_password
Publish Test Message:
- Connect to your MQTT server
- Publish to topic:
temperature - Message:
25.5 - Watch
OnMessageReceived()in your app logs
Configuration Reference
MQTT Configuration
{
"MQTT": {
"UserName": "your_username",
"Password": "your_password",
"Host": "localhost",
"Port": "1883"
}
}
| Property | Required | Description | Default |
|---|---|---|---|
UserName |
✅ Yes | MQTT client username | - |
Password |
✅ Yes | MQTT client password | - |
Host |
✅ Yes | MQTT broker hostname/IP | localhost |
Port |
✅ Yes | MQTT broker port | 1883 |
Auto-loaded by: EnvironmentHelper.GetConfiguration()
Real-World Examples
Example 1: IoT Telemetry Dashboard
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
builder.Services.AddDbContext<TelemetryDbContext>();
// ✅ MQTT server + client for telemetry
builder.Services.AddMQTTServer<TelemetryHandler, MQTTServerServiceBase>("sensors/#");
var app = builder.Build();
app.MapRazorPages();
app.MapHub<DashboardHub>("/dashboardHub");
app.Run();
// TelemetryHandler.cs
public class TelemetryHandler : MQTTClientServiceBase
{
private readonly IServiceProvider _services;
public TelemetryHandler(string topic, IServiceProvider services)
: base(topic)
{
_services = services;
}
public override void OnMessageReceived(string message)
{
using var scope = _services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<TelemetryDbContext>();
var hub = scope.ServiceProvider.GetRequiredService<IHubContext<DashboardHub>>();
// Parse sensor data
var data = JsonSerializer.Deserialize<SensorReading>(message);
// Save to database
db.SensorReadings.Add(data);
db.SaveChanges();
// Push to dashboard in real-time
hub.Clients.All.SendAsync("NewReading", data);
}
}
Example 2: Smart Home Automation
public class SmartHomeHandler : MQTTClientServiceBase
{
private readonly ILogger<SmartHomeHandler> _logger;
private readonly IHubContext<SmartHomeHub> _hub;
public SmartHomeHandler(
string topic,
ILogger<SmartHomeHandler> logger,
IHubContext<SmartHomeHub> hub)
: base(topic)
{
_logger = logger;
_hub = hub;
}
public override void OnMessageReceived(string message)
{
var command = JsonSerializer.Deserialize<HomeCommand>(message);
switch (command.Device)
{
case "light":
_logger.LogInformation($"Light {command.Action}: {command.Value}");
_hub.Clients.All.SendAsync("LightUpdate", command);
break;
case "thermostat":
_logger.LogInformation($"Thermostat set to: {command.Value}°C");
_hub.Clients.All.SendAsync("ThermostatUpdate", command);
break;
case "door":
_logger.LogWarning($"Door {command.Action}");
// Trigger security notification
_hub.Clients.All.SendAsync("SecurityAlert", command);
break;
}
}
}
public class HomeCommand
{
public string Device { get; set; } // "light", "thermostat", "door"
public string Action { get; set; } // "on", "off", "set"
public string Value { get; set; } // "25.5", "locked"
}
Test Commands:
// Turn on living room light
{"Device": "light", "Action": "on", "Value": "100"}
// Set thermostat
{"Device": "thermostat", "Action": "set", "Value": "22.5"}
// Lock front door
{"Device": "door", "Action": "locked", "Value": "true"}
Example 3: Industrial Equipment Monitoring
public class EquipmentMonitor : MQTTClientServiceBase
{
private readonly IServiceProvider _services;
public EquipmentMonitor(string topic, IServiceProvider services)
: base(topic)
{
_services = services;
}
public override void OnMessageReceived(string message)
{
using var scope = _services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<FactoryDbContext>();
var alerts = scope.ServiceProvider.GetRequiredService<IAlertService>();
var reading = JsonSerializer.Deserialize<MachineReading>(message);
// Store reading
db.MachineReadings.Add(reading);
// Check thresholds
if (reading.Temperature > 85)
{
alerts.SendAlert($"Machine {reading.MachineId} overheating: {reading.Temperature}°C");
}
if (reading.Vibration > 5.0)
{
alerts.SendAlert($"Machine {reading.MachineId} excessive vibration: {reading.Vibration}");
}
db.SaveChanges();
}
}
public class MachineReading
{
public string MachineId { get; set; }
public double Temperature { get; set; }
public double Vibration { get; set; }
public double Pressure { get; set; }
public DateTime Timestamp { get; set; }
}
API Reference
Extension Methods
// Add MQTT server + client with custom handler
services.AddMQTTServer<TClientService, TServerService>(string topic)
where TClientService : MQTTClientServiceBase
where TServerService : MQTTServerServiceBase
Base Classes
MQTTClientServiceBase
public abstract class MQTTClientServiceBase : IHostedService
{
protected MQTTClientServiceBase(string topic);
// Override this method to handle messages
public abstract void OnMessageReceived(string message);
// Lifecycle methods (auto-implemented)
public Task StartAsync(CancellationToken cancellationToken);
public Task StopAsync(CancellationToken cancellationToken);
}
MQTTServerServiceBase
public class MQTTServerServiceBase : IHostedService
{
public Task StartAsync(CancellationToken cancellationToken);
public Task StopAsync(CancellationToken cancellationToken);
}
Configuration Model
public class MQTTConfig
{
public string UserName { get; set; }
public string Password { get; set; }
public string Host { get; set; }
public string Port { get; set; }
}
Best Practices
- ✅ Use topic wildcards -
sensors/#to subscribe to all sensors - ✅ JSON payloads - Structured data is easier to parse
- ✅ Handle exceptions - Network issues are common in IoT
- ✅ Use DI in handlers - Inject services via constructor
- ✅ Log all messages - Debugging distributed systems is hard
- ✅ Set QoS levels - QoS 1 (at least once) for critical data
- ⚠️ Don't block
OnMessageReceived()- UseTask.Run()for heavy work
Troubleshooting
Issue: "Connection refused" when starting server
Cause: Port 1883 already in use
Fix:
{
"MQTT": {
"Port": "1884" // Use different port
}
}
Issue: Messages not received
Cause: Topic mismatch or subscription not active
Fix:
// Check topic in handler matches published topic
builder.Services.AddMQTTServer<Handler, MQTTServerServiceBase>("exact/topic/name");
// Use wildcards for multiple topics
builder.Services.AddMQTTServer<Handler, MQTTServerServiceBase>("sensors/#");
Issue: "Invalid credentials" error
Cause: Username/password in appsettings.json doesn't match server config
Fix:
{
"MQTT": {
"UserName": "correct_username",
"Password": "correct_password"
}
}
FAQ
1. Can I run multiple clients for different topics?
Yes! Register multiple handlers:
services.AddMQTTServer<TemperatureHandler, MQTTServerServiceBase>("temperature");
services.AddMQTTServer<HumidityHandler, MQTTServerServiceBase>("humidity");
2. How do I send messages (publish)?
Inject IManagedMqttClient and use PublishAsync():
public class SensorService
{
private readonly IManagedMqttClient _mqttClient;
public async Task PublishTemperature(double temp)
{
var message = new MqttApplicationMessageBuilder()
.WithTopic("temperature")
.WithPayload(temp.ToString())
.Build();
await _mqttClient.PublishAsync(message);
}
}
3. Can I use MQTT over TLS/SSL?
Yes! Update connection options:
options.WithTls(new MqttClientOptionsBuilderTlsParameters
{
UseTls = true,
AllowUntrustedCertificates = false
});
Related CHD Packages
| Package | Description | NuGet |
|---|---|---|
| Chd.Common | Infrastructure primitives (config, extensions, encryption) | NuGet |
| Chd.Logging | Structured logging with Serilog (Graylog, MSSQL, file) | NuGet |
| Chd.Caching | Redis distributed caching with AOP attributes | NuGet |
Contributing
Found a bug? Have a feature request?
- Issues: GitHub Issues
- Pull Requests: GitHub PRs
Authors
- Mehmet Yoldaş (LinkedIn)
See also contributors on NuGet
License
This package is free and open-source under the MIT License.
Made with ❤️ by the CHD Team
Cleverly Handle Difficulty 📡
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Chd.Library.Common (>= 8.7.1)
- Chd.Library.Logging (>= 8.7.0)
- Microsoft.Extensions.Configuration (>= 10.0.3)
- Microsoft.Extensions.Configuration.CommandLine (>= 10.0.3)
- Microsoft.Extensions.Configuration.EnvironmentVariables (>= 10.0.3)
- Microsoft.Extensions.Configuration.Json (>= 10.0.3)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Hosting (>= 10.0.3)
- MQTTnet (>= 4.3.3.952)
- MQTTnet.Extensions.ManagedClient (>= 4.3.3.952)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.