Getting Started with MQTT

Written by The HiveMQ Team

Category: MQTT

Published: April 24, 2020


Introduction to MQTT

MQTT is a standard for moving data between an IoT device and a server. Originally developed in 1999 by Andy Standford-Clark and Arlen Nipper to monitor oil and gas pipelines over remote satellite connections, MQTT has become the de-facto IoT standard for connecting all sorts of IoT devices. Today, all major IoT platforms, IoT cloud services providers, and many IoT edge gateways and devices support connectivity with MQTT.

MQTT is a publish/subscribe protocol that is lightweight and requires a minimal footprint and bandwidth to connect an IoT device. Unlike HTTP’s request/response paradigm, MQTT is event driven and enables messages to be pushed to clients. This type of architecture decouples the clients from each other to enable a highly scalable solution without dependencies between data producers and data consumers.

MQTT Publish/Subscribe

MQTT Publish/Subscribe Architecture

The key benefits of MQTT are:

  1. Lightweight and efficient to minimize resources required for the client and network bandwidth.
  2. Enables bidirectional communication between devices and servers. Also, enabling broadcasting messages to groups of things.
  3. Scales to millions of things.
  4. MQTT specifies Quality of Service (QoS) levels to support message reliability.
  5. MQTT supports persistent sessions between device and server that reduces reconnection time required over unreliable networks.
  6. MQTT messages can be encrypted with TLS and support client authentication protocols.

MQTT Use Cases

MQTT is used in many industries and applications. HiveMQ has published a number of case studies from industries such as automotive (BMW), telecommunications (Liberty Global), energy (Fortum), public safety (Hytera), connected products (Awair, Matternet) and more.

Basic Concepts

At the core of MQTT is the MQTT broker and the MQTT clients. The MQTT broker is responsible for dispatching messages between the sender and the rightful receivers. An MQTT client publishes a message to a broker and other MQTT clients can subscribe to the broker to receive messages. Each MQTT message includes a topic. An MQTT client publishes a message to a specific topic and MQTT clients subscribe to the topics they want to receive. The MQTT broker uses the topics and the subscriber list to dispatch messages to appropriate MQTT clients.

An MQTT broker is able to buffer messages that can’t be dispatched to MQTT clients that are not connected. This becomes very useful for situations where network connections are unreliable. To support reliable message delivery, MQTT supports 3 different types of quality of services messages: 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. Most commercial MQTT brokers now support MQTT 5 but many of the IoT managed cloud services only support MQTT 3.1.1. We highly recommend new IoT deployments to use MQTT 5 due to the new features that focus on more robust systems and cloud native scalability.

For a more in depth description of the MQTT protocol, we recommend that you read the MQTT Essentials series of articles or review the companion video series. MQTT 5 Essentials series also provides an in depth introduction to the MQTT 5 specific features.

MQTT Clients

There are many open source MQTT clients available in a wide range of programming languages. HiveMQ offers the HiveMQ MQTT Client that is developed in Java. Eclipse Paho also offers C/C++, Python and a variety of other implementations. A detailed list of MQTT clients can be found at mqtt.org.

MQTT Brokers

MQTT brokers are offered in open source, commercial implementations and managed cloud services. HiveMQ offers two commercial editions: HiveMQ Professional and HiveMQ Enterprise, a managed cloud MQTT service: HiveMQ Cloud, and an open source version: HiveMQ Community Edition. A detailed list of MQTT brokers can be found at mqtt.org.

Example Implementation

To better illustrate how MQTT works, we present a simple example implementation that uses HiveMQ MQTT Client and the HiveMQ public broker that is available for experimentation.

Use Case

In this example we will have a temperature and brightness sensor connected to a Raspberry Pi that will send the sensor data to an MQTT broker. Another device will run a control center that receives the MQTT data.

Use Case Communication Flow

Communication between the sensor client and the control center over MQTT

Step 1 - Implement sensor client

The first step is to create the MQTT client that publishes the sensor data. In this example, we will use a thermometer and brightness sensor. We will also use the HiveMQ public broker, which is a publicly accessible MQTT broker used for experimenting with MQTT.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class Sensor {

    public static void main(String[] args) throws InterruptedException {
        // 1. create the client
        final Mqtt5Client client = Mqtt5Client.builder()
                .identifier("sensor-" + getMacAddress()) // use a unique identifier
                .serverHost("broker.hivemq.com") // use the public HiveMQ broker
                .automaticReconnectWithDefaultConfig() // the client automatically reconnects
                .build();

        // 2. connect the client
        client.toBlocking().connectWith()
                .willPublish()
                    .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);
        }
    }

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

The above code snippet does the following:

  1. It creates the MQTT client. It is important to use a unique identifier. We use automatic reconnect because the sensor internet connection may be unstable.
  2. It connects the client to broker.hivemq.com. As a will is specified, the broker automatically publishes the “sensor gone” message if the sensor loses its connection.
  3. Then it periodically publishes (simulated) brightness and temperature data.

Step 2 - Implement subscribing client

The next step is implementing the subscribing client, which consumes the values on the topics home/temperature and home/brightness.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class ControlCenter {

    public static void main(String[] args) {
        // 1. create the client
        final Mqtt5Client client = Mqtt5Client.builder()
                .identifier("controlcenter-" + getMacAddress()) // use a unique identifier
                .serverHost("broker.hivemq.com") // use the public HiveMQ broker
                .automaticReconnectWithDefaultConfig() // the client automatically reconnects
                .build();

        // 2. connect the client
        client.toBlocking().connectWith()
                .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 above code snippet does the following:

  1. It creates the MQTT client. The initialization of the MQTT client instance is almost the same as for the sensor, except we use controlcenter- as prefix for the client id.
  2. It connects the client to broker.hivemq.com. We use a session expiry interval of 1 hour to buffer messages when then control center is offline.
  3. It subscribes the client to all topics starting with home so we use the multi-level wildcard # in the topic filter. All arriving messages are printed out with topic and payload. When the sensor loses its connection, it prints the topic home/will and the payload “sensor gone”.

Next Steps

Now that you have a good introduction to MQTT we suggest the following:

  1. Read the MQTT Essentials and MQTT 5 Essentials series of articles to learn more technical details about MQTT.
  2. Try out HiveMQ to get hands-on experience. Download an evaluation license of our HiveMQ commercial edition. We also have the HiveMQ MQTT Client, the MQTT CLI for easy testing of MQTT systems, and a Getting Started tutorial.
  3. Contact HiveMQ to discuss your requirements for MQTT and IoT messaging. Our experts have lots of experience helping companies build reliable and scalable IoT applications.

About The HiveMQ Team

We love writing about MQTT, IoT protocols and architecture in general. Our experts are here to help, so reach out to us if we can help!
Contact us
Top 5 Best Practices when Scalability testing your MQTT Broker
HiveMQ ESE 1.5.1 released