Skip to content

MQTT Tutorial: An Easy Guide to Getting Started with MQTT

by HiveMQ Team
(updated on ) 17 min read

Introduction to MQTT

MQTT is a publish/subscribe protocol designed for connecting IoT devices. Unlike HTTP’s request/response paradigm, MQTT operates in an event-driven manner, allowing messages to be pushed to clients. This architectural approach enables highly scalable solutions by decoupling data producers and data consumers, eliminating dependencies between them. Two key components to establish MQTT connection for publishing and subscribing of the messages are MQTT Clients and MQTT Broker as shown in the diagram below.

MQTT Publish SubscribeMQTT Publish/Subscribe Architecture

Benefits of MQTT

MQTT offers several key benefits:

  1. Lightweight and efficient: MQTT minimizes the resources required by clients and network bandwidth.

  2. Bidirectional communication: MQTT facilitates communication between devices and servers, supporting publishing and subscribing. It also allows broadcasting messages to groups of devices.

  3. Scalability: MQTT can scale to support millions of devices or “things” in an IoT or IIoT ecosystem.

  4. Quality of Service (QoS) levels: MQTT specifies different QoS levels to ensure reliable message delivery.

  5. Persistent sessions: MQTT supports persistent sessions between devices and servers, reducing reconnection time over unreliable networks.

  6. Security features: MQTT supports TLS encryption for message confidentiality and authentication protocols for client verification.

From Automotive to Energy: Real-World Applications and Use Cases of MQTT

MQTT finds applications across various industries and domains. It has been adopted by companies such as BMW, Liberty Global, Fortum, Hytera, Awair, and Matternet, as showcased in HiveMQ’s customer success stories. These companies have successfully leveraged MQTT in automotive, telecommunications, energy, public safety, and connected product domains.

MQTT Basics: Mastering the Essentials of this IoT Protocol

At the core of MQTT are MQTT brokers and MQTT clients. The MQTT broker is an intermediary between senders and receivers, dispatching messages to the appropriate recipients. MQTT clients publish messages to the broker, and other clients subscribe to specific topics to receive messages. Each MQTT message includes a topic, and clients subscribe to topics of their interest. The MQTT broker maintains a subscriber list and uses it to deliver messages to the relevant clients.

An MQTT broker can also buffer messages for disconnected clients, ensuring reliable message delivery even in unreliable network conditions. To achieve this, MQTT supports three different Quality of Service (QoS) levels: 0 (at most once), 1 (at least once), and 2 (exactly once).

There are two versions of the MQTT specification: MQTT 3.1.1 and MQTT 5. While most commercial MQTT brokers now support MQTT 5, some IoT-managed cloud services still primarily support MQTT 3.1.1. We highly recommend using MQTT 5 for new IoT deployments due to its enhanced features that focus on robustness and cloud-native scalability.

For a comprehensive understanding of the protocol, we highly recommend delving into the MQTT Essentials series of articles or exploring the companion MQTT Essentials video series. Additionally, the MQTT 5 Essentials series offers a detailed introduction to the specific features of MQTT 5.

MQTT Clients

Many open source clients are available in a variety of programming languages. HiveMQ provides its own MQTT clients through HiveMQ MQTT Client Libraries, which are designed to simplify the deployment and implementation of MQTT clients and offer users top-notch functionality, performance, security, and reliability. Some of the programming languages supported include C#, C++, Java, Websockets, Python, and more. Eclipse Paho also offers MQTT client libraries for languages like C/C++ and Python.

MQTT Brokers

MQTT Brokers come in various implementations, catering to different needs, such as open-source, commercial, and managed cloud services. HiveMQ offers commercial editions: HiveMQ Self-Managed. and HiveMQ Cloud, a managed cloud MQTT service, and HiveMQ Community Edition, an open-source version. For an extensive list of MQTT brokers, please visit mqtt.org.

If you are looking to find the ideal MQTT broker for your IoT or industry 4.0 use case, read our article MQTT Broker Comparison – Which is the Best for Your IoT Application?

Example Implementation of MQTT

To illustrate how MQTT works, below is a simple example that utilizes HiveMQ Cloud. To test this implementation on a live cluster, sign-up for HiveMQ Cloud Serverless plan, which allows you to connect up to 100 IoT devices at no cost. Sign-up without credit card information.

As a first-time user, HiveMQ Cloud seamlessly redirects you to the dedicated “Getting Started” section within the management view of your cluster, ensuring a smooth and hassle-free onboarding experience. To get you started, refer the below use case example that was tested on Java 11. This example serves as a valuable resource to help you get up and running quickly. We’ve also prepared a publicly hosted example in our ready-to-go Github repository, along with an example tailored for our public broker.

MQTT Use Case Example:

IoT Application Built Using Raspberry Pi, MQTT, and Temperature Sensor

In this example, we explore the connection of a temperature and brightness sensor to a Raspberry Pi, leveraging the power of MQTT to transmit sensor data to a designated MQTT broker effortlessly. Discover how another device, acting as a control center, can effortlessly receive and process the MQTT data, enabling efficient monitoring and control of your IoT ecosystem.

MQTT Pub/SubCommunication between the sensor client and the control center over MQTT

Step 1 - Use the Raspberry Pi as an MQTT Client Connected to Sensors

Let’s begin your MQTT journey by creating a powerful MQTT client to publish sensor data. In this step, we’ll utilize a thermometer, brightness sensor, and the robust HiveMQ Cloud as our MQTT broker. Once you’ve successfully signed up for HiveMQ Cloud, head to the Details section on the Overview tab of your cluster. There, you’ll discover your unique hostname. Copy this hostname and replace it in the code snippet provided below. There you will find your hostname. Copy this hostname to replace it in the example code snippet below.

HiveMQ Cloud Serverless Cluster Details OverviewCreating MQTT credentials is essential to establishing a secure connection between your MQTT client and the cluster.

Navigate to the Access Management tab of your HiveMQ Cloud Basic Serverless cluster and define your MQTT credentials. This can be done by defining Username, Password and assigning specific Permissions to those credentials.

HiveMQ Cloud Cluster Access ManagementBy default, all available credentials are assigned the publish and subscribe role. The list of the credentials created and their permission are displayed as shown in the screenshot above.
HiveMQ Cloud Serverless Access Management's Permission dashboardIf you want to change the role assigned to a credential pair, you can do so during creation. To update the role assigned to a credential, delete the existing credential pair and create a new one. To apply the new role to your clients, reconnect them after creating credentials with an updated role. You can also create custom permissions with specific topic filters and assign them to your credentials.

Let’s dive into the exciting world of MQTT with confidence and efficiency. Once you have created your HiveMQ Cloud cluster, copy the hostname as suggested above and replace it in the code snippet.

public class Sensor {

    public static void main(String[] args) throws InterruptedException {
        final String host = "<your_host>"; // use your host-name, it should look like '<alphanumeric>.s2.eu.hivemq.cloud'
        final String username = "<your_username>"; // your credentials
        final String password = "<your_password>";
   
        // 1. create the client
        final Mqtt5Client client = Mqtt5Client.builder()
                .identifier("sensor-" + getMacAddress()) // use a unique identifier
                .serverHost(host) 
                .automaticReconnectWithDefaultConfig() // the client automatically reconnects
                .serverPort(8883) // this is the port of your cluster, for mqtt it is the default port 8883
                .sslWithDefaultConfig() // establish a secured connection to HiveMQ Cloud using TLS
                .build();
                

        // 2. connect the client
        client.toBlocking().connectWith()
                .simpleAuth() // using authentication, which is required for a secure connection
                .username(username) // use the username and password you just created
                .password(password.getBytes(StandardCharsets.UTF_8))
                .applySimpleAuth()
                .willPublish() // the last message, before the client disconnects
                    .topic("home/will")
                    .payload("sensor gone".getBytes())
                    .applyWillPublish()
                .send();

        // 3. simulate periodic publishing of sensor data
        while (true) {
            client.toBlocking().publishWith()
                    .topic("home/brightness")
                    .payload(getBrightness())
                    .send();

            TimeUnit.MILLISECONDS.sleep(500);

            client.toBlocking().publishWith()
                    .topic("home/temperature")
                    .payload(getTemperature())
                    .send();

            TimeUnit.MILLISECONDS.sleep(500);
        }
    }
        //4. Simulate Temperature and Brightnes sensor data
    private static byte[] getBrightness() {
        // simulate a brightness sensor with values between 1000lux and 10000lux
        final int brightness = ThreadLocalRandom.current().nextInt(1_000, 10_000);
        return (brightness + "lux").getBytes(StandardCharsets.UTF_8);
    }

    private static byte[] getTemperature() {
        // simulate a temperature sensor with values between 20°C and 30°C
        final int temperature = ThreadLocalRandom.current().nextInt(20, 30);
        return (temperature + "°C").getBytes(StandardCharsets.UTF_8);
    }
}

Let’s dissect the code snippet provided above to understand its functionality:

  1. Creating the MQTT Client: The code initializes the MQTT client, ensuring a unique identifier is used. An automatic reconnect feature is also enabled to handle potential instability in the sensor’s internet connection.

  2. Establishing Connection to "<your_host>": The client connects to the specified host. Notably, a “will” message is set, allowing the broker to automatically publish a “sensor gone” notification if the sensor loses its connection.

  3. Periodic Publication of Simulated Sensor Data: The code periodically publishes simulated brightness and temperature data using the methods getBrightness() and getTemperature() methods, ensuring a steady stream of information for further processing.

With this code snippet, you can confidently create an MQTT client, establish a stable connection, and regularly transmit vital sensor data.

Now, let’s move on to the next step in our implementation process:

Step 2 - Implementing the Subscribing Client

In this crucial step, we focus on creating the subscribing client responsible for consuming the values published on the topics home/temperature and home/brightness.

Implementing the subscribing client enables the reception of sensor data transmitted via MQTT. This functionality allows you to process and utilize the received information for various applications efficiently.

public class ControlCenter {

    public static void main(String[] args) {
        final String host = "<your_host>"; // use your host-name, it should look like '<alphanumeric>.s2.eu.hivemq.cloud'
        final String username = "<your_username>";  // your credentials
        final String password = "<your_password>";
   
        // 1. create the client
        final Mqtt5Client client = Mqtt5Client.builder()
                .identifier("controlcenter-" + getMacAddress()) // use a unique identifier
                .serverHost(host) 
                .automaticReconnectWithDefaultConfig() // the client automatically reconnects
                .serverPort(8883) // this is the port of your cluster, for mqtt it is the default port 8883
                .sslWithDefaultConfig() // establish a secured connection to HiveMQ Cloud using TLS
                .build();

        // 2. connect the client
        client.toBlocking().connectWith()
                .simpleAuth() // using authentication, which is required for a secure connection
                .username(username) // use the username and password you just created
                .password(password.getBytes(StandardCharsets.UTF_8))
                .applySimpleAuth()
                .cleanStart(false)
                .sessionExpiryInterval(TimeUnit.HOURS.toSeconds(1)) // buffer messages
                .send();

        // 3. subscribe and consume messages
        client.toAsync().subscribeWith()
                .topicFilter("home/#")
                .callback(publish -> {
                    System.out.println("Received message on topic " + publish.getTopic() + ": " +
                            new String(publish.getPayloadAsBytes(), StandardCharsets.UTF_8));
                })
                .send();
    }
}

The code snippet above performs the following actions:

  1. Creates an MQTT client instance, similar to the sensor client, with the client ID prefixed as controlcenter-.

  2. Establishes a connection between the client and the specified host in <your_host>. To ensure message buffering when the control center is offline, a session expiry interval of 1 hour is set.

  3. Subscribes the client to all topics starting with home using the multi-level wildcard # in the topic filter. Any incoming messages with their corresponding topic and payload are printed. If the sensor loses connection, the topic home/will and the payload “sensor gone” are printed.

By implementing both the sensor client and the subscribing client, you can establish a seamless MQTT communication system where sensor data is published and consumed by the control center, enabling efficient monitoring and control of devices.

Next Steps

Now that you’ve gained a basic understanding of MQTT, congratulations! However, the world of MQTT is vast, and there’s always room for more knowledge. To fuel your ongoing learning journey, we highly recommend exploring these additional resources:

Dive deeper into the MQTT protocol by exploring our resources that offer a wealth of technical details to enhance your understanding.

  1. Take a glance at MQTT FAQs and MQTT Glossary, which provides a concise overview of key MQTT terminologies, allowing you to grasp them quickly and easily.

  2. Read the MQTT Essentials and MQTT 5 Essentials series of articles to learn more technical details about the protocol.

  3. For those who prefer a locally-hosted solution, you can explore the evaluation license of our HiveMQ Platform. This option allows you to experience the benefits of HiveMQ while running it on your infrastructure.

  4. We also have the HiveMQ MQTT Client and the MQTT CLI for easy testing of MQTT systems.

  5. If you have specific requirements or need guidance regarding MQTT and IoT messaging, feel free to Contact HiveMQ. Our team of experts has extensive experience in assisting companies with developing reliable and scalable IoT applications. We’ll be more than happy to discuss your unique needs and provide tailored solutions.

Remember, MQTT is an exciting and evolving field; there’s always more to explore and discover.

FAQs on MQTT

HiveMQ Team

The HiveMQ team loves writing about MQTT, Sparkplug, Industrial IoT, protocols, how to deploy our platform, and more. We focus on industries ranging from energy, to transportation and logistics, to automotive manufacturing. Our experts are here to help, contact us with any questions.

HiveMQ logo
Review HiveMQ on G2