Summit
EMQ Sponsors Open Source Summit Europe 2024 | Register Now →

How to Process JSON, Hex, and Binary Data in MQTT

EMQX Team
May 22, 2024
How to Process JSON, Hex, and Binary Data in MQTT

Introduction to MQTT Payload

MQTT payload refers to the actual data carried in an MQTT message. The MQTT protocol does not impose any requirements on the Payload format; it allows for any binary data. In practice, however, we have some general data formats in the application layer, such as JSON, Binary, Hex, and Protobuf.

Understanding the payload format and its management is crucial, as this represents the primary information exchanged between devices in the IoT ecosystem. In this blog, we will explain how these formats are transmitted and processed with the MQTT Broker and MQTT Client.

You can read this blog to learn more about MQTT payload: Introduction to MQTT Payload Format Indicator and Content Type | MQTT 5 Features

Common Message Transmission Data Formats in MQTT

Plain Text

Plain Text, the simplest format, is usually used for the transmission of various simple text messages, such as instant chatting, message notifications, etc. For example:

Hi, this is a plain text.

JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for machines to parse and generate and also for humans to read and write. It is often used to describe an Object or event. For example:

{"temperature": "22.1"}

Raw Binary

Raw binary data refers to data that is in a format that is not intended for human interpretation. It consists of sequences of binary digits (0s and 1s) that represent information such as text, images, audio, video, or any other type of data. This data is typically stored in a computer's memory or on storage devices in its binary form. Generally, we write raw binaries in hexadecimal. For example the Raw binary of String aaa written as:

0x616161

Hex String

Hex String is a way to describe a segment of Raw binary in the form of its hexadecimal chars. For example, the Hex String of the String aaa is String 616161. The Hex String is typically used for the encoding of raw binary data, which is converted into a visible hexadecimal string. This format is convenient for reading and printing more than Raw Binary.

Protobuf

Protocol Buffers (Protobuf) is a free and open-source cross-platform data format used to serialize structured data. It is useful in developing programs that communicate with each other over a network or for storing data. For example, the message Schema like the following:

message Sensor {
  required int32 temperature = 1;
}

Then a Protobuf message binary representing a temperature of 22 is:

0816

Sending and Receiving Data in Different Formats

Setting up the Practice Environment

MQTT Broker

EMQX is a highly scalable and feature-rich MQTT broker designed for IoT and real-time messaging applications.

In this tutorial, we use Docker to install an EMQX 5.6.1 locally for demonstration:

docker run  --rm -p 18083:18083 -p 1883:1883  emqx/emqx:5.6.1

Then open the browser and visit http://127.0.0.1:18083 to enter the EMQX Dashboard. The default username and password are admin, public :

EMQX Dashboard

MQTT Client

We recommend using MQTTX CLI as the MQTT client for testing. MQTTX is an open-source, cross-platform MQTT 5.0 desktop client initially developed by EMQ, which can run on macOS, Linux, and Windows.

Get MQTTX CLI here.

Take MacOS as an example, install MQTTX CLI:

brew install emqx/mqttx/mqttx-cli

After successful, test if it can establish a connection to the local EMQX:

mqttx conn -h 127.0.0.1 -p 1883

For example, getting the following output proves a successful connection to the local EMQX:

Connect to the local EMQX

Sending and Receiving Messages

The Payload of MQTT messages supports any format of strings or binary. For example, we use MQTTX CLI to create a subscriber named sub to EMQX and subscribe the test/sub topic:

mqttx sub -h 127.0.0.1 -p 1883 -i sub -t test/sub

Then, publish a simple message to test/sub topic, i.e:

mqttx pub -h 127.0.0.1 -p 1883 -i pub -t test/sub -m 'Hi, plaintext payload'

We can observe that the subscriber on the bottom has received this message:

received message

Content-Type Field of Payload

In the MQTT 5.0 protocol, the Content-Type field was introduced to identify the Payload format (see: Content Type in PUBLISH message).

Therefore, we can use this field when publishing messages to enhance the description of the Payload format:

mqttx pub -h 127.0.0.1 -p 1883 -i pub -t test/sub -m 'Hi, plaintext payload' --content-type 'plain/text'

We can observe that the subscriber on the bottom has received this message and content type setting:

plain/text message

Payload in JSON Format

JSON is a lightweight data interchange format that is easily readable and writable by humans and easily parsed and generated by machines.

We can also send a JSON format message through the MQTTX CLI. This operation is similar to plain text messages.

Note: the --format parameter is used to inform the MQTTX CLI that the input Payload is a JSON string and to validate its legality:

mqttx pub -h 127.0.0.1 -p 1883 -i pub -t test/sub \\
  --content-type 'application/json' \\
  --format json \\
  -m '{"key": "value"}'

We can also get output like the following:

JSON message

Payload in Hex String Format

Hexadecimal String (Hex String) is a representation of binary data as a string of hexadecimal numbers. Each byte of binary data is represented by a two-digit hexadecimal number, allowing for a more human-readable format. It's commonly used in programming and data communication.

In MQTT, a Hex String can be sent directly as a normal string:

mqttx pub -h 127.0.0.1 -p 1883 -i pub -t test/sub \\
  -m '31310000ffff'

We can get the output like the following:

Hex String message

Payload in Binary Format

According to the MQTT protocol definition, the format of the payload is not constrained, meaning it can be in any binary format.

MQTTX CLI can send binary data through --format hex, for example:

mqttx pub -h 127.0.0.1 -p 1883 -i pub -t test/sub \\
--format hex \\
-m '31 31 00 00 ff ff'

The screenshot below illustrates that the receiver displays the binary as 11��. This is because 0x31 is the encoded representation of the character 1:

Binary format message

Handle JSON Payload with EMQX Rule Engine

The rule engine feature of EMQX provides various processing functions that can conveniently handle the parsing and extraction of various payload formats. Learn more at: EMQX Rule Engine.

For structured payloads with JSON format, the EMQX Rule Engine can conveniently extract and reorganize the fields within it. We will demonstrate in detail how to handle JSON payload with EMQX Rule Engine in this section.

Create Rule and Action

For example, we can add the following rule to extract the JSON field via EMQX Dashboard:

SELECT
  payload.temperature as t
FROM
  "test/msg_in"

The purpose of this rule is to parse and extract the temperature from the message payload on all test/msg_in topics. And rename the field to t.

Then, add a Republish action to this rule to publish the message in the new JSON structure to the test/msg_out topic.

Add the Rule and Action:

Add the Rule and Action

The Republish Action parameters:

The Republish Action parameters

Test with MQTTX CLI

Once the rule is created, we can use MQTTX CLI to verify it by using the following command to create a subscription to the topic test/msg_out :

mqttx sub -h 127.0.0.1 -p 1883 -i sub -t test/msg_out -v

Then publish the JSON formatted message {"temperature": 23.5, "altitude": 100} to the test/msg_in topic:

mqttx pub -h 127.0.0.1 -p 1883 -i pub -t test/msg_in \\
  --format json \\
  -m '{"temperature": 23.5, "altitude": 100}'

By observing the messages received by the subscriber at test/msg_out, we can see that the temperature in the JSON message has been extracted and reformatted as {"t": 23.5} :

Test with MQTTX CLI

Q&A

Which data format is most suitable for my application?

The choice of data format really depends on the needs of your specific application. For instance, if you need a human-readable format and aren't overly concerned about bandwidth, JSON might be the best choice. However, if bandwidth is a concern, a more compact format like binary or hexadecimal might be better. If you need a balance between structure and efficiency but can accept the complexity, Protobuf could be the right choice.

Can I send images or other large files as MQTT payloads?

While it's technically possible to send images or other large files as MQTT payloads, it's generally not recommended. MQTT was designed for small, frequent messages, and sending large payloads can cause network congestion or other issues.

What is the maximum size of an MQTT payload?

The maximum size of the MQTT payload is 256 MB. However, considering the performance and efficiency of the network, payloads are generally recommended to be kept below 1 MB.

Can I encrypt MQTT payloads?

Yes, MQTT payloads can be encrypted before being sent and then decrypted upon receipt. This can provide an additional layer of security for sensitive data. However, you must perform encryption when sending messages and decryption when receiving messages.

Conclusion

In conclusion, MQTT provides a flexible way to exchange data between IoT devices in various formats. The choice of payload data format depends on the specific requirements of the application, such as network bandwidth, human readability, and the complexity of the data structure. With a proper understanding of these different formats and how to handle them in MQTT, developers can optimize their IoT solutions for efficiency and performance.

Talk to an Expert
Contact Us →