Chd.MQTT 8.5.7

dotnet add package Chd.MQTT --version 8.5.7
                    
NuGet\Install-Package Chd.MQTT -Version 8.5.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Chd.MQTT" Version="8.5.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Chd.MQTT" Version="8.5.7" />
                    
Directory.Packages.props
<PackageReference Include="Chd.MQTT" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Chd.MQTT --version 8.5.7
                    
#r "nuget: Chd.MQTT, 8.5.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Chd.MQTT@8.5.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Chd.MQTT&version=8.5.7
                    
Install as a Cake Addin
#tool nuget:?package=Chd.MQTT&version=8.5.7
                    
Install as a Cake Tool

Chd.MQTT 📡

NuGet Downloads License: MIT

Chd.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?

Chd.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


Stop Reinventing MQTT Setup! ⏰

Every IoT project needs MQTT. Stop configuring MQTTnet brokers manually. Chd.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 Chd.MQTT?

Problem Without Chd.MQTT With Chd.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 MQTTClientServiceBase for 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 Chd.MQTT

NuGet Package Manager:

Install-Package Chd.MQTT

Package Reference (.csproj):

<PackageReference Include="Chd.MQTT" Version="8.5.6" />

Quick Start Guide

Step 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 temperature topic
  • ✅ Handles messages in TemperatureHandler

Step 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; }
}

Step 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:

  1. Connect to your MQTT server
  2. Publish to topic: temperature
  3. Message: 25.5
  4. 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

  1. ✅ Use topic wildcards - sensors/# to subscribe to all sensors
  2. ✅ JSON payloads - Structured data is easier to parse
  3. ✅ Handle exceptions - Network issues are common in IoT
  4. ✅ Use DI in handlers - Inject services via constructor
  5. ✅ Log all messages - Debugging distributed systems is hard
  6. ✅ Set QoS levels - QoS 1 (at least once) for critical data
  7. ⚠️ Don't block OnMessageReceived() - Use Task.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
});

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?

  1. Issues: GitHub Issues
  2. Pull Requests: GitHub PRs

Authors

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.5.7 95 3/2/2026