Message Queuing Telemetry Transport

MQTT Communications Suite

MQTT is a Client Server publish/subscribe messaging transport protocol. It is light weight, open, simple, and designed so as to be easy to implement. These characteristics make it ideal for use in many situations, including constrained environments such as for communication in Machine to Machine (M2M) and Internet of Things (IoT) contexts where a small code footprint is required and/or network bandwidth is at a premium. – Oasis, MQTT Standards document, 2014. Read more here.

Introduction

The MQTT Suite is a project that I conducted within the third year of university. It was the cornerstone of my education on threading and concurrency. The project brief was as follows:

  • Implement a Client MQTT utility that could connect to any server running the MQTT standard and receive and send messages as well as manage topical subscriptions.
  • Implement a Broker that any Client running the MQTT standard can connect to so that it may perform server tasks. Further to this, the Broker must remain able to handle its inner workings whilst maintaining connections with an arbitrary amount of Clients.
  • Implement a Configuration Client that acts as a Client but has the authority to shut down the Broker  as well as perform any tasks deemed necessary. Further to this, it must be able to petition the Broker for a list of its currently connected Clients and their respective subscriptions, however the Configuration Client need not be compatible with other Brokers.

The Client

m2The Client was the logical first step, as their had been a test Broker provided to get used to the protocol. It was designed in WPF C# using custom XAML resource dictionaries (style sheets). The image show to the right shows the subscriptions page, a page where if the client has subscribed to some topics, you will be able to see any information being published to that topic in the watch window.

The Broker

m3The Broker came second after the client was solidly built to withstand any kind of anomaly. I’d also built in a heavy amount of debugging so I could easily access what it was exactly the two programs were sending and receiving. The Broker to the left is a simple C# Console Application using multiple threads to sustain itself.

Example Log of the Broker

The Broker logs to the window itself but also logs incrementally to a XML file, as well as saving the data its received to a separate XML file.

<?xml version="1.0" encoding="utf-8"?>
<Entries>
  <Entry Time="00:30" Date="01/10/2015" Value="Session Starts" />
  <Entry Time="00:32" Date="01/10/2015" Value="127.0.0.1:14470 Opened a Connection." />
  <Entry Time="00:32" Date="01/10/2015" Value="Connection Packet Recieved From '127.0.0.1:14470'." />
  <Entry Time="00:32" Date="01/10/2015" Value="Connection From '127.0.0.1:14470' [883053102] Approved. Sending Connection Acknowledgement..." />
  <Entry Time="00:32" Date="01/10/2015" Value="Subscription Recieved From '127.0.0.1:14470' [883053102]." />
  <Entry Time="00:32" Date="01/10/2015" Value="Subscriptions Added for '127.0.0.1:14470' [883053102].&#xA;0 Succeeded, 1 Failed." />
  <Entry Time="00:33" Date="01/10/2015" Value="127.0.0.1:14471 Opened a Connection." />
  <Entry Time="00:33" Date="01/10/2015" Value="Connection Packet Recieved From '127.0.0.1:14471'." />
  <Entry Time="00:33" Date="01/10/2015" Value="Connection From '127.0.0.1:14471' [201305388] Approved. Sending Connection Acknowledgement..." />
  <Entry Time="00:33" Date="01/10/2015" Value="Client at '127.0.0.1:14470' [883053102] Published on Topic 'CMD/Broker/Config'." />
  <Entry Time="00:33" Date="01/10/2015" Value="Master Command Recieved" />
  <Entry Time="00:33" Date="01/10/2015" Value="Listing Clients and Subscriptions." />
  <Entry Time="00:33" Date="01/10/2015" Value="Subscription Recieved From '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:33" Date="01/10/2015" Value="Subscriptions Added for '127.0.0.1:14471' [201305388].&#xA;1 Succeeded, 0 Failed." />
  <Entry Time="00:33" Date="01/10/2015" Value="Subscription Recieved From '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:33" Date="01/10/2015" Value="Subscriptions Added for '127.0.0.1:14471' [201305388].&#xA;1 Succeeded, 0 Failed." />
  <Entry Time="00:33" Date="01/10/2015" Value="Ping Request Recieved from '127.0.0.1:14471' [201305388]. Replying..." />
  <Entry Time="00:33" Date="01/10/2015" Value="Publishling on Topic: 'LoopBack' to '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:33" Date="01/10/2015" Value="Client at '127.0.0.1:14471' [201305388] Published on Topic 'Topic1'." />
  <Entry Time="00:33" Date="01/10/2015" Value="Publishling on Topic: 'Topic1' to '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:34" Date="01/10/2015" Value="Client at '127.0.0.1:14470' [883053102] Published on Topic 'CMD/Broker/Config'." />
  <Entry Time="00:34" Date="01/10/2015" Value="Master Command Recieved" />
  <Entry Time="00:34" Date="01/10/2015" Value="Listing Clients and Subscriptions." />
  <Entry Time="00:34" Date="01/10/2015" Value="Publishling on Topic: 'LoopBack' to '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:34" Date="01/10/2015" Value="Ping Request Recieved from '127.0.0.1:14471' [201305388]. Replying..." />
  <Entry Time="00:34" Date="01/10/2015" Value="Publishling on Topic: 'LoopBack' to '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:35" Date="01/10/2015" Value="Publishling on Topic: 'LoopBack' to '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:35" Date="01/10/2015" Value="Ping Request Recieved from '127.0.0.1:14471' [201305388]. Replying..." />
  <Entry Time="00:35" Date="01/10/2015" Value="Publishling on Topic: 'LoopBack' to '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:36" Date="01/10/2015" Value="Publishling on Topic: 'LoopBack' to '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:36" Date="01/10/2015" Value="Ping Request Recieved from '127.0.0.1:14471' [201305388]. Replying..." />
  <Entry Time="00:36" Date="01/10/2015" Value="Publishling on Topic: 'LoopBack' to '127.0.0.1:14471' [201305388]." />
  <Entry Time="00:36" Date="01/10/2015" Value="'127.0.0.1:14470' [883053102] Unresponsive for 60 Seconds. Closing Connection..." />
  <Entry Time="00:37" Date="01/10/2015" Value="'127.0.0.1:14471' [201305388] Unresponsive for 60 Seconds. Closing Connection..." />
</Entries>

The Configuration Client

m1The Configuration Client was the third to be created, it was designed in WPF C# using custom XAML resource dictionaries (style sheets). Show the right, the Client publishes on a specialist ‘CMD/Broker/Config’ topic that only a client with the Configuration Clients special Client ID can communicate on. We can see from the console window that it has recently petitioned the Broker for a list of active clients, picking up itself (as a client) and one other client.

Further Reading

  • Threading & Concurrency Programming >>
  • Working with MQTT Packets >>