Geschreven door Steffen van den Driest

Wat is het MQTT protocol?

Development8 minuten leestijd

In het verleden heb ik veel met het MQTT protocol gewerkt. Dit protocol bestaat al een tijd en wordt steeds vaker gebruikt, met name in smart home/IoT projecten. Doordat ik dit protocol steeds meer terug zie komen, leek het mij leuk om in deze blog uitleg te geven over wat dit protocol precies is, waar het voor gebruikt wordt en wat de voor- en nadelen zijn. Aansluitend heb ik een stuk code gemaakt dat gebruikt kan worden om het MQTT protocol uit te proberen. 

Wat is het? 

MQTT is een client/server protocol dat gebruikmaakt van een publish/subscribe principe. Het protocol wordt tegenwoordig voornamelijk gebruikt voor IoT (Internet of Things) doeleinden. Het protocol is in eerste instantie bedacht om met een lage bandbreedte, weinig energie en lage installatiekosten oliepijpleidingen te monitoren. Dit ging namelijk via satelliet verbindingen en was erg kostbaar. Tegenwoordig wordt MQTT in vele industrieën (zoals auto, logistiek, olie & gas) gebruikt. Daarnaast wordt dit protocol massaal gebruikt in smart-home oplossingen. 

MQTT bevindt zich in de applicatielaag van het OSI model en maakt gebruik van TCP/IP als transport. Hierdoor is het te gebruiken op een standaard netwerk en is er geen speciale hardware nodig om er mee te kunnen werken. Naast dat MQTT snel is en weinig bandbreedte vraagt, is het goed schaalbaar en zijn de berichten data agnostisch. Dit laatste houdt in dat het in principe niet uit maakt wat voor type data verstuurd wordt, hoewel berichten in JSON formaat het meest worden gebruikt. 

Hoe werkt het? 

In deze blog zal ik de fundamentele basisprincipes van het MQTT protocol uitleggen. Meer informatie hierover is te vinden in de specificatie

Publish en Subscribe 

Publish/subscribe is de methode die gebruikt wordt door het MQTT protocol en dient als een alternatief voor de request/response (polling) methode. Het voordeel van deze methode is dat alleen geïnteresseerde clients berichten ontvangen, wat efficiënt is voor het netwerkverkeer. 

De publish/subscribe methode werkt als volgt: als gebruiker kun je je "abonneren" (subscribe) op een topic waar je geïnteresseerd in bent. Wat een topic exact inhoudt wordt later uitgelegd. Gebruikers kunnen berichten sturen (publish) op topics. Zodra een bericht verstuurd is op een topic, zullen gebruikers die geabonneerd zijn op het topic het bericht ontvangen. Gebruikers die niet geabonneerd zijn op het topic zullen overgeslagen worden en zullen het bericht niet ontvangen.

Een voorbeeld dat het wellicht duidelijker maakt is het abonneren op een YouTube kanaal. Zodra op dat kanaal nieuwe content verschijnt, krijgen abonnees hier bericht van, terwijl andere YouTube gebruikers dit bericht niet krijgen. 

Figuur 1. Publish/subscribe voorbeeld 

De illustratie hierboven laat zien dat een temperatuursensor een nieuwe waarde verstuurd naar het topic "building1/room1/temperature". Naast de temperatuursensor is in de illustratie te zien dat er drie andere clients zijn. Van deze drie clients zijn er twee die geabonneerd zijn op het topic van de temperatuursensor. Deze twee clients krijgen dan ook het gepubliceerde bericht binnen, de andere client krijgt hier niks van te zien. 

Broker 

De broker is het hart van het MQTT protocol. De broker is een centraal punt waar MQTT gebruikers (clients) zich op aanmelden. De broker houdt bij welke clients verbonden zijn en op welke topics zij zich hebben geabonneerd. Zodra de broker dus een bericht binnen krijgt van een bepaald topic, filtert de broker de clients die zijn geabonneerd op dat topic en stuurt vervolgens het bericht naar alleen deze clients. De illustratie hieronder laat hetzelfde principe zien als de illustratie gebruikt bij Publish en Subscribe. Echter deze keer met een broker als centraal punt. 

Figure 2. Publish/subscribe met broker voorbeeld 

De belangrijkste verantwoordelijkheden van de broker zijn: 

  • Het bijhouden van topics waar clients op zijn geabonneerd en welke clients dit zijn.
  • Het doorsturen van berichten naar gebruikers die zijn geabonneerd op het topic.
  • Het bijhouden van client data. 
  • Autorisatie van clients.
    Autorisatieregels kunnen opgesteld worden per client. Deze regels stellen welke topics beschikbaar zijn, welke operaties toegestaan zijn (publish en/of subscribe. 
  • Authenticatie van clients.
    Authenticatieregels kunnen opgesteld worden om te bepalen wat voor clients nodig is om met de broker te kunnen verbinden. Dit kan door het aanmaken en implementeren van een password file bij de broker configuratie. In dit bestand staat aangegeven welke gebruikersnamen acceptabel zijn met een versleuteld wachtwoord. Alleen de combinatie van de juiste gebruikersnaam en wachtwoord geven toegang tot de broker. Een andere vorm van authenticatie is het gebruik van een X.509 certificaat. 

De broker heeft ook de mogelijkheid om het berichtverkeer te versleutelen. Dit gebeurt door middel van TLS certificaten die toegevoegd kunnen worden aan de configuratie van de broker. Hier boven werd de X.509 certificaat genoemd als vorm van authenticatie, dit kan verwerkt worden in een TLS certificaat. De client biedt een client certificaat aan en bij de zogeheten TLS handshake zal dan de authenticatie uitgevoerd worden. Meer informatie over het TLS protocol is te vinden via deze link

Topics 

Een topic is een punt dat de broker gebruikt om berichten te filteren voor de clients. Een topic kan uit meerdere niveaus bestaan, hierbij wordt een "/" gebruikt als scheidingsteken voor de niveaus. Doordat topics uit meerdere niveaus kunnen bestaan is het dus mogelijk om een hiërarchie te maken. Een goed voorbeeld hiervoor is "gebouwnaam/verdiepingsnaam/ruimtenaam/sensortype-/waarde". Naast topicniveaus heeft MQTT ook wildcards geïntroduceerd. Door een wildcard te gebruiken is het mogelijk om te abonneren of berichten te versturen op meerdere topics met een enkel statement. 

Topics hoeven niet eerst aangemaakt te worden. De broker accepteert elk topic zolang het maar minstens 1 karakter en geen spaties, speciale tekens of wildcard symbolen bevat. Let wel op dat topics hoofdlettergevoelig zijn. 

Voor- en nadelen 

MQTT biedt veel voordelen, maar brengt ook nadelen met zich mee. Hieronder is een klein overzicht van belangrijke voor- en nadelen: 

Voordelen 
  • Weinig resources 
    MQTT verbruikt minimale resources, hierdoor is het protocol geschikt voor kleine microcontrollers. 
  • Lage bandbreedte 
    MQTT gebruikt kleine headers voor de berichten, hierdoor wordt bespaard op bandbreedte
  • Eenvoudig te implementeren 
    Open protocol dat geen additionele hardware vereist. 
  • IoT ready 
    MQTT kan gebruikt worden voor IoT projecten. 
  • Goed schaalbaar 
    MQTT netwerken kunnen wel uitbreiden tot miljoenen clients. 
  • Data agnostisch 
    Berichten kunnen verstuurd worden in elk format. 
  • Security 
    TLS encryptie en authenticatie mogelijkheden. 
  • Keuze in betrouwbaarheid bericht verkeer 
    Quality of Service niveau is instelbaar 
  • Ondersteuning voor onbetrouwbare netwerken (Session awareness) 
    Het is mogelijk om client sessies tijdelijk te laten onthouden door de broker, hierdoor zal opnieuw verbinden erg snel gaan. 
Nadelen 
  • Single-point of failure 
    Een actieve broker is nodig om een MQTT sessie actief te houden. 

Uitvoering 

Nu een uitleg is gegeven over het MQTT protocol, is natuurlijk nog de vraag hoe dit in de soft ware uitgevoerd kan worden. Het code voorbeeld is te vinden door te klikken op deze link. In dit voorbeeld is te zien hoe met een broker verbonden kan worden. Vervolgens zal er geabonneerd worden op een topic waarbij later een bericht verstuurd wordt. De printlines zullen bevestigen dat het bericht verstuurd en ook ontvangen is. Als laatste zal de sessie worden afgesloten door de verbinding met de broker te verbreken. Om deze code uit te kunnen voeren, is het van belang dat de juiste libraries worden geïmporteerd. In dit voorbeeld is gebruikgemaakt van de Paho library. Dit is een open source library van Eclipse die onder andere via Maven of Gradle is te importeren. Klik op deze link voor meer informatie. 

In het code voorbeeld is gebruikgemaakt van een online broker instantie die gratis te gebruiken is. Het is ook mogelijk om zelf lokaal een broker te configureren en starten. Een veel gebruikte broker is de Mosquitto broker. Ook deze software is een open source project van Eclipse. Klik op deze link voor meer informatie. De standaard configuratie zal al voldoende zijn om de code te kunnen gebruiken. Het is dan wel nodig om de BROKER String aan te passen naar het IP adres of domein adres waar de broker wordt gebruikt. Bij lokaal gebruik is hier het adres "tcp://localhost:1883" vol doende voor. 

Zoals te zien is in het broker adres, is dit meer dan alleen het IP of domein adres. Deze String bevat nog een prefix en een suffix. De prefix, in dit geval "tcp", staat voor wat voor soort verbinding opgezet moet worden. Hierbij is de keuze uit "tcp" voor onbeveiligd en "ssl" voor een beveiligde verbinding. De suffix bestaat uit een reeks cijfers, in dit geval "1883". Dit is het poortnummer waar de broker gebruik van maakt. Standaard staan MQTT brokers zo ingesteld dat "1883" gebruikt wordt voor een onveilige verbinding en "8883" voor een beveiligde verbinding. Uiteraard zijn andere poortnummers ook mogelijk. 

Als de libraries succesvol zijn geïmporteerd en de code wordt uitgevoerd zal het volgende resultaat moeten verschijnen: 

Connecting to broker: tcp://test.mosquitto.org:1883
Connected
Subscribing to topic: l2mqtt/exampleTopic
Publish message to topic: l2mqtt/exampleTopic
Published message!
Received message from topic: l2mqtt/exampleTopic
Message: Test message
Disconnected

Vervolg

In deze blog heb ik de theoretische basisprincipes van het MQTT protocol uitgelegd en door middel van een code voorbeeld geïllustreerd. Het protocol is echter het beste uit te leggen door middel van een toegepast voorbeeld. Daarom laat ik in mijn volgende blog een leuke toepassing zien van het MQTT protocol in een Minecraft-mod.