Tech Solution Stack

Tech Solution Stack – Tech Solution Stack is a blog sharing practical guide and tutorials on modern tech solutions for developers.

ads header

Thursday, November 13, 2025

Getting Started with MQTT using Mosquitto and .NET client as Publisher and Subscriber

Getting Started

In the world of IoT and real-time communication, MQTT (Message Queuing Telemetry Transport) has become one of the most popular lightweight messaging protocols. It is designed for scenarios where network bandwidth and device resources are limited, making it perfect for sensors, controllers, and connected applications. If you want to know more about MQTT vs AMQP refer to our earlier blog post MQTT vs AMQP: Key Differences, Use Cases, and Tools

In this blog, we’ll walk through a hands-on introduction to MQTT using the Mosquitto broker. We’ll learn how to:

  •  Use Mosquitto clients (mosquitto_pub and mosquitto_sub) to publish and subscribe to MQTT topics.
  • Build a Python client for subscribing and processing messages.
  • Use QoS level
  • Set up secure communication using TLS to ensure data privacy and authentication.

By the end of this tutorial, we’ll have a complete understanding of how MQTT works in practice, from publishing messages to subscribing clients, all running over a secure, lightweight messaging infrastructure.

Setting Up the Mosquitto MQTT Broker

Before we start publishing and subscribing to messages, let’s set up our MQTT broker. We’ll use Eclipse Mosquitto, one of the most popular open source MQTT brokers, known for its simplicity and reliability.

If you want to know more about software licensing type then go for our previous blog post Software Licenses: Open Source vs Proprietary

Install Mosquitto (Windows OS)

Download the Mosquitto installer from the official Mosquitto website https://mosquitto.org/download/

Run the installer and select the options to install both broker and client tools.

Once installed, verify the installation by running command  mosquitto -v
Verify the Broker is Running

Once the broker is up, test its default port (1883 for non-TLS):

netstat -an | findstr 1883
If mosquito is running following result should come in response


Test Basic Publish/Subscribe

Open two terminals, in terminal 1 subscribe to a topic and in terminal 2 publish to a topic.

Terminal 1 – Subscribe to a topic:

mosquitto_sub -h localhost -t test/topic

Terminal 2 – Publish a message:

mosquitto_pub -h localhost -t test/topic -m "Hello MQTT!"

As soon as the message will publish in Terminal 2, the same will appear in terminal 1 

Creating a .NET MQTT Client to Subscribe and Receive Messages

Once the Mosquitto broker is live, we can connect to it programmatically using an MQTT client library. In .NET, the most popular and reliable choice is MQTTnet, an open-source library that fully supports MQTT v3.1.1 and v5.

Let’s walk through the process of building a simple subscriber in C#.

1. Create a New .NET Console Application

Open visual studio and create a new .NET Console Application “MQTT.NETSubscriber”

2. Install the MQTTnet Package

Right click on solution project and click on Manage Nuget Package to open it. Browse for MQTTnet library and install the latest stable version.

Note: - In the code example I have used MQTTNet v3.1.2 for .NET framework 4.7.2
If you are using .NET Core feel free to use the higher compatible version

3. Write the MQTT Subscriber Code

I have created a separate class file having methods to create MQTT instances, connect to MQTT broker and subscribe for events from topic. In the main method I am calling for subscription.

The full project can be found in the GITHub repo. 

Program.cs code

using System.Threading.Tasks;

using System.Configuration;

namespace MQTT.NETSubscriber

{

    public class Program

    {

        static async Task Main(string[] args)

        {

            string broker = ConfigurationManager.AppSettings["Broker"];

            int port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);

            string testTopic = ConfigurationManager.AppSettings["Topic"];        

MQTTSubscriber mQTTSubscriber = new MQTTSubscriber(broker, port);

            await mQTTSubscriber.ConnectAsync();

            await mQTTSubscriber.SubscribeAsync(testTopic);         

Console.WriteLine("Waiting for messages. Press any key to exit...");          

Console.ReadKey();

            await mQTTSubscriber.DisconnectAsync();

        }

    }

}

MQTTSubscriber.cs code

public class MQTTSubscriber

{

    private MqttFactory _factory;

  private IMqttClient _client;

    private IMqttClientOptions _clientOptions;

    public MQTTSubscriber(string broker,int? port)

    {

        // Create a new MQTT client

        _factory = new MqttFactory();

        _client= _factory.CreateMqttClient();

        // Configure client options

        _clientOptions = new MqttClientOptionsBuilder()   

.WithTcpServer(broker, port)

        .WithClientId("DotNetSubscriber")

        .Build();

        // Attach message handler (old syntax for v3.x)    

_client.ApplicationMessageReceivedHandler =

            new MqttApplicationMessageReceivedHandlerDelegate(OnMessageReceived);

    }

    public async Task ConnectAsync()

    {   

Console.WriteLine("Subscriber is connecting to MQTT broker...");

        await _client.ConnectAsync(_clientOptions);   

Console.WriteLine("Subscriber connected successfully!");

    }

    public async Task SubscribeAsync(string topic)

    {

        if (!_client.IsConnected)

        {         

Console.WriteLine("Client not connected. Connecting now...");

            await ConnectAsync();

        }

        await _client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic(topic).Build());  

Console.WriteLine($"Subscriber subscribed to topic: {topic}");

    }

    public async Task DisconnectAsync()

    {

        await _client.DisconnectAsync();

Console.WriteLine("Disconnected from MQTT broker.");

    }

    #region private methods

    // Message handler (for v3.x)

    private void OnMessageReceived(MqttApplicationMessageReceivedEventArgs e)

    {

        string topic = e.ApplicationMessage.Topic;

        string message = Encoding.UTF8.GetString(e.ApplicationMessage.Payload ?? Array.Empty<byte>());

Console.WriteLine($"Message received on topic '{topic}': {message}");

    }

    #endregion

}

Check the result

Run the .NET program

Open a command prompt and use Mosquitto_pub command to publish a message to topic TestTopic1 like below :

>mosquitto_pub -h localhost -t TestTopic1 -m "Hello MQTT!!!!!!!"

You can find the message is printing in .NET program console window.

Creating a .NET MQTT Client to Publish Messages

We’ll use the same MQTTnet v3.1.2 library, but this time focus on sending messages to a topic that our subscriber can receive.

public class MQTTPublisher

{

    private readonly MqttFactory _factory;

    private readonly IMqttClient _client;

    private readonly IMqttClientOptions _clientOptions;

    public MQTTPublisher(string broker, int? port)

    {

        // Create MQTT client

        _factory = new MqttFactory();

        _client = _factory.CreateMqttClient();

        // Configure client options

        _clientOptions = new MqttClientOptionsBuilder()        

.WithTcpServer(broker, port)       

.WithClientId("DotNetPublisher")

            .Build();

    }

    // Connect to broker

    public async Task ConnectAsync()

  {      

Console.WriteLine("Publisher is connecting to MQTT broker...");

        await _client.ConnectAsync(_clientOptions);     

Console.WriteLine("Publisher connected successfully!");

    }

    // Publish message to topic

    public async Task PublishAsync(string topic, string message)

    {

        if (!_client.IsConnected)

        {       

Console.WriteLine("Client not connected. Connecting now...");

            await ConnectAsync();

        }

        var mqttMessage = new MqttApplicationMessageBuilder()          

.WithTopic(topic)         

.WithPayload(Encoding.UTF8.GetBytes(message))         

.WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)       

.WithRetainFlag(false)

            .Build();

        await _client.PublishAsync(mqttMessage);     

Console.WriteLine($"Message published to '{topic}': {message}");

    }

    // Disconnect from broker

    public async Task DisconnectAsync()

    {

        await _client.DisconnectAsync();     

Console.WriteLine("Disconnected from MQTT broker.");

    }

}

Change the program.cs file to invoke publisher methods . So once the program will run both publisher and subscriber should connect to MQTT broker where publisher will be ready to publish and subscriber will be listening the topic.

static async Task Main(string[] args)

{

    string broker = ConfigurationManager.AppSettings["Broker"];

    int port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);

    string topic = ConfigurationManager.AppSettings["Topic"];

    // Create both subscriber and publisher instances

    var subscriber = new MQTTSubscriber(broker, port);

    var publisher = new MQTTPublisher(broker, port);

    // Connect both

    await subscriber.ConnectAsync();

    await subscriber.SubscribeAsync(topic);

    await publisher.ConnectAsync();

    Console.WriteLine("Publisher connected. Type messages to publish (type 'exit' to quit).");

    // Publish messages and see them received by the subscriber

    while (true)

    {

        Console.Write("Message: ");

        string message = Console.ReadLine();

        if (string.Equals(message, "exit", StringComparison.OrdinalIgnoreCase))

            break;

        await publisher.PublishAsync(topic, message);

    }

    // Disconnect both

    await publisher.DisconnectAsync();

    await subscriber.DisconnectAsync();

    Console.WriteLine("Disconnected both clients. Press any key to exit...");

    Console.ReadKey();

}

Now we can see the result that once we publish any message, the same message is available to subscriber.

Understanding and Implementing MQTT QoS Levels in .NET

let’s dive into the next topic in our list QoS (Quality of Service) Levels. This is one of the most important MQTT concepts for reliable message delivery.

MQTT defines three Quality of Service (QoS) levels that determine how reliably messages are delivered between the publisher and subscriber.

QoS

Level Name

Guarantee

Description

0

At most once

No acknowledgement

Message is delivered once, if possible, but can be lost. Fastest but least reliable.

1

At least once

Guaranteed delivery, may be duplicate

Broker stores message until it gets an acknowledgment (PUBACK). Subscriber may get duplicates.

2

Exactly once

Guaranteed delivery, exactly once

Safest but slowest — ensures message is received only once using a 4-step handshake.

1aWe can configure QoS in both publisher and subscriber.

Set QoS in Subscriber.cs

public async Task SubscribeAsync(string topic, int qosLevel = 1)

{

    if (!_client.IsConnected)

    {

        Console.WriteLine("Client not connected. Connecting now...");

        await ConnectAsync();

    }

    var qos = (MQTTnet.Protocol.MqttQualityOfServiceLevel)qosLevel;

    await _client.SubscribeAsync(new MqttTopicFilterBuilder()

        .WithTopic(topic)

        .WithQualityOfServiceLevel(qos)

        .Build()

        );

    Console.WriteLine($"Subscriber subscribed to topic: {topic} with QoS {qosLevel}");

}

In previous publisher code we are already used QoS 1

Setting Up Secure MQTT Communication Using TLS

As MQTT is often used in IoT systems and enterprise integrations, securing communication between clients and brokers is essential. Without encryption, sensitive information can be intercepted or tampered with during transmission. To protect your data, MQTT supports Transport Layer Security (TLS) ensuring that messages are securely transmitted and both client and broker can authenticate each other.

1.      Get the CA certificate

The very first step is to get the certificate from trusted certificate authority. It’s like a notary office that says: “I verify that this organization’s identity is legitimate.” It owns a private key (ca.key) and public certificate (ca.crt).

2.      Create the Broker Certificate (Server Certificate)

Our MQTT broker (Mosquitto) needs it’s own certificate like identity card. This certificate (server.cert) contains it’s public key and identity info (like CN=Localhost). But the world won’t trust this certificate unless signed by a CA.we have to sign the broker certificate using CA private key.

Step1

So, first we have to create the private key of the broker (server.key) using openssl .

Step2

Then create a certificate signing request (CSR).

CRS contains

1.public key derived from private key

2.The broker’s identity details like CN,organization, etc

Step3

Sign the broker CSR with CA certificate and key to generate server certificate

3.      How MQTT Client(publisher/subscriber) authenticate MQTT broker

When client connects to broker, the broker presents it’s certificate(server.cert). The client then check who signed it by seeing the CA info inside it.The client is already having the CA’s public certificate (CA.cert) to verify the signature.

If the verification succeeds then broker is authentic else no.

Setting Up Secure MQTT Communication Using TLS

As MQTT is often used in IoT systems and enterprise environments, securing communication between clients and brokers is essential. Without encryption, sensitive data can be intercepted or tampered with during transmission. To ensure confidentiality and authenticity, MQTT supports Transport Layer Security (TLS)  which encrypts messages and allows both client and broker to verify each other’s identity.

1.Get the CA Certificate

The first step is to get a certificate from a trusted Certificate Authority (CA).
Think of the CA like a digital notary office that says: “I verify that this organization’s identity is legitimate.”

The CA owns:

  • a private key (ca.key) – used to sign other certificates
  • a public certificate (ca.crt) – used by clients to verify signatures

If you’re testing locally, you can create your own self-signed CA using OpenSSL.

2.Create the Broker Certificate (Server Certificate)

Your MQTT broker (Mosquitto) needs its own digital identity card — the server certificate (server.crt).
This file contains the broker’s public key and identity details (like CN=localhost).

However, the world (clients) won’t trust this certificate unless it’s signed by the CA.
That’s why we must use the CA’s private key to sign the broker’s certificate.

Step 1: Create the broker’s private key

openssl genrsa -out server.key 2048

Step 2: Create a Certificate Signing Request (CSR)

openssl req -new -key server.key -out server.csr

The CSR includes:

  • The broker’s public key
  • Identity details such as CN (Common Name), Organization, etc.

Step 3: Sign the CSR using the CA’s certificate and key

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \

-out server.crt -days 365 -sha256

This produces the server certificate (server.crt) signed by the CA.

3.How MQTT Clients Authenticate the Broker

When a client (publisher/subscriber) connects to the broker:

  1. The broker presents its certificate (server.crt).
  2. The client checks who signed it by reading the CA information inside the certificate.
  3. The client uses its trusted CA certificate (ca.crt) to verify the broker’s certificate signature.

If the verification succeeds, the client trusts the broker and establishes a secure TLS connection.
If not, the connection is rejected ensuring that the client never talks to an untrusted server.

Generated documents summary Table

File Name

Description

Purpose

Used By

CA.key

Private key of the CA

Used to sign and issue other certificate

CA

CA.cert

Public certificate of the CA

Shared with clients so they can verify certificates signed by CA

Client

Server.key

Private key of the MQTT Broker

Used to encrypt and authenticate messages from the broker

Broker

Server.csr

Certificate signing request

Contains broker’s public key and identity details sent to CA for signing

Temporary during creation

Server.cert

Signed certificate from MQTT Broker

Proves the broker’s identity to client. Used in TLS handshake

Broker

To be continued for..

4.Configuring Mosquitto for TLS Communication

5. Configuring .NET MQTT Client for Secure TLS Connection


No comments:

Post a Comment

Powered by Blogger.

Subscribe by Email

Search This Blog

Post Top Ad

ad728