Message Queuing Telemetry Transport er designet til ustabile netværk,
begrænset båndbredde og tusindvis af små enheder. Her får du teorien
bag pub/sub — og en live Opla-demo på samme side.
~2 B
Min. header
1883
TCP-port
3
QoS-niveauer
Pub/Sub
Mønster
Wire log
live
CONNECTopla-mkr1010
CONNACKrc=0 accepted
SUBSCRIBEdemo/opla/cmd/#
PUBLISHdemo/opla/temp → 22.4
PUBLISHdemo/opla/cmd/led/2 → 255,40,0
PINGREQkeep-alive
01 Hvad er MQTT?
MQTT er en letvægts publish/subscribe-protokol, der kører
oven på TCP/IP. Den blev skabt i 1999 af IBM og Arcom (Andy Stanford-Clark
& Arlen Nipper) til at sende telemetri fra oliepipelines over satellit —
altså netværk med høj latency, pakketab og dyr båndbredde.
I dag er MQTT de facto-standarden for mange IoT-systemer: smarte bygninger,
industri (IIoT), wearables, home automation og cloud-platforme som AWS IoT,
Azure IoT Hub og HiveMQ. OASIS har standardiseret protokollen; MQTT 3.1.1
og MQTT 5.0 er de mest udbredte versioner i undervisning og produktion.
PUB
Publish
En klient sender en besked med topic + payload til brokeren. Den kender ikke sine modtagere.
SUB
Subscribe
En klient beder brokeren om at levere fremtidige beskeder, der matcher ét eller flere topics.
BRK
Broker
Central router, der holder forbindelser, matcher topics og leverer beskeder til de rigtige klienter.
Kerneidé: Afsender og modtager er løst koblede.
Arduino Opla behøver ikke vide, at pensum-siden, C#-dashboardet eller
andre klienter lytter — den publicerer bare til et topic.
02 Hvorfor MQTT er god til IoT
IoT-enheder har typisk lidt RAM/flash, kører på batteri eller ustabilt
WiFi, og skal kunne håndtere tusindvis af samtidige forbindelser. MQTT
er bygget til præcis det — i modsætning til klassisk HTTP.
HTTP Request/Response
Klienten spørger gentagne gange (polling)
Stor header-overhead pr. request
Kortvarige forbindelser = mere TCP-handshake
Server svarer kun når den bliver spurgt
God til web-API’er, tung til små sensorer
MQTT Event-drevet
Push når noget sker — ingen unødvendig polling
Minimal fixed header (ofte 2 bytes)
Langvarig TCP-session + keep-alive
Broker pusher til alle subscribers med det samme
Designet til telemetri og kommandoer
Konkrete IoT-fordele
01
Lav overhead
En temperatur kan sendes som få bytes payload. Mindre radio = længere batteritid og billigere data.
02
Many-to-many
Én Opla kan forsyne web, C# og logging samtidigt — bare flere subscribers på samme topic.
03
Ustabilt net
QoS, clean/persistent session og keep-alive hjælper, når WiFi falder ud midlertidigt.
04
Bidirektionelt
Samme forbindelsen brugt til telemetri og kommandoer (fx RGB-LED fra websiden).
05
Skalérbarhed
Brokere er bygget til mange samtidige klienter. Topics organisere data uden hårde API-kontrakter.
06
Status-awareness
Last Will fortæller resten af systemet, når en enhed mister forbindelsen uventet.
Hvornår MQTT ikke er det bedste valg
Store filoverførsler / media streaming (brug HTTP, WebRTC, S3 osv.)
Komplekse request/response-API’er med streng REST-semantik
Browser-apps uden WebSocket-broker (almindelig MQTT-TCP virker ikke direkte i browseren)
03 Sådan virker protokollen
MQTT er en binær protokol. Hver “pakke” (control packet) har en lille
header, valgfri variable header og payload. Klient og broker taler
ved hjælp af et fast sæt pakettyper.
Vigtigste pakettyper
Pakke
Retning
Formål
CONNECT
Klient → Broker
Opret session: Client ID, keep-alive, username/password, Last Will, Clean Session
CONNACK
Broker → Klient
Bekræft (eller afvis) forbindelsen med return code
PUBLISH
Begge veje
Selve beskeden: topic, payload, QoS, retain-flag
SUBSCRIBE / SUBACK
Klient ↔ Broker
Tilmeld topics + bekræft maksimalt QoS
UNSUBSCRIBE
Klient → Broker
Afmeld topics
PINGREQ / PINGRESP
Begge veje
Keep-alive: “er du der endnu?”
DISCONNECT
Klient → Broker
Pæn afkobling (uden at trigge Last Will)
PUBACK / PUBREC / PUBREL / PUBCOMP
Begge veje
QoS 1 og QoS 2 bekræftelser
Forbindelses-livscyklus
1. TCP-forbindelse
Klient åbner TCP til broker (typisk port 1883 eller 8883 for TLS).
Hvis der er stille for længe, sendes PINGREQ. Svarer brokeren ikke, anses forbindelsen for død.
5. DISCONNECT eller brud
Pæn lukning med DISCONNECT — eller abrupt brud, som kan udløse Last Will.
Ports & transport
1883 — standard MQTT over TCP (ukrypteret)
8883 — MQTT over TLS
8080/8083 m.fl. — MQTT over WebSocket (det browsere bruger)
Denne pensumservers browser-demo bruger WebSocket på port
8888. Arduino Opla bruger klassisk TCP på 1883.
04 Pub/Sub-arkitektur
I modsætning til HTTP’s request/response er MQTT event-drevet.
Enheder publicerer, når noget sker — de poller ikke en server.
Publisher
Arduino Opla
→
PUBLISH demo/opla/temp
Broker
:1883
→
DELIVER demo/opla/temp
Subscriber
Web / C#
Tre roller i jeres projekt
Publisher — Opla
Læser sensorer og sender temp, fugt, lys. Subscribe også på demo/opla/cmd/# for LED-kommandoer.
Broker — denne server
Aedes-broker i Docker. Router beskeder mellem alle klienter på TCP og WebSocket.
Subscriber — pensumsiden
Browser-MQTT via WebSocket. Viser live data og publicerer RGB-kommandoer tilbage.
Decoupling i praksis: I kan starte/stoppe web-demoen uden
at Opla “går i panik”. Når siden forbinder igen, får den nye PUBLISH’er —
og med retain kan den endda få seneste status med det samme.
05 Topics & wildcards
Topics er UTF-8-strenge, der fungerer som “adresser” for beskeder.
Hierarkiet adskilles med /. Brokeren matcher dem — den
fortolker ikke payload’en.
demo/
opla/status
opla/temp
opla/humidity
opla/light
opla/button
opla/cmd/led/0 … /4
opla/cmd/buzzer
skole/
rum/101/temp
rum/101/humidity
rum/102/temp
Naming conventions (god praksis)
Små bogstaver, hierarki fra groft → fint: bygning/etage/rum/sensor
Undgå ledende / (det skaber et tomt første niveau)
Adskil kommandoer fra telemetri: .../cmd/... vs .../temp
Hold payload simple (tal, JSON, korte strenge)
Wildcards (kun ved subscribe)
Wildcard
Betydning
Eksempel
+
Præcis ét niveau
demo/opla/+ matcher demo/opla/temp, men ikke demo/opla/cmd/led/0
#
Nul eller flere niveauer (kun sidst)
demo/opla/# matcher alt under Opla — også kommandoer og dybe topics
I live-demoen subscriber I automatisk til demo/opla/#,
så både sensorer og status dukker op.
06 Quality of Service i dybden
QoS er en kontrakt mellem afsender og broker — og mellem
broker og subscriber. De to kan have forskellige niveauer;
den lavere “vinder” typisk i den samlede leveringsgaranti.
QoS 0At most once — “Fire and forget”. Ingen bekræftelsespakke.
Hurtigst og billigst i radio. Besked kan gå tabt ved pakketab.
QoS 1At least once — PUBLISH → PUBACK. Brokeren bekræfter.
Beskeden kommer frem mindst én gang, men kan duplikeres (DUP-flag).
QoS 2Exactly once — 4-vejs handshake: PUBLISH → PUBREC → PUBREL → PUBCOMP.
Ingen tab og ingen dobbeltbehandling. Dyrst i traffic og kompleksitet.
QoS 2-flow (forenklet)
PUBLISHAfsender sender besked med Packet ID
PUBRECModtager: “modtaget — gemt midlertidigt”
PUBRELAfsender: “du må frigive / committe den”
PUBCOMPModtager: “færdig — præcis én levering”
Hvornår bruger man hvad?
QoS 0 Periodisk telemetri (temp hvert 5. sekund) — et tab gør ikke noget
QoS 1 Alarmer, knap-events, statusændringer — vigtigt, men duplikat er OK
QoS 2 Kritiske kommandoer / transaktioner — må ikke køres dobbelt
Tommelfingerregel til Opla-projektet: sensorer på QoS 0,
LED-kommandoer på mindst QoS 0/1, Last Will/status gerne med retain.
07 Retain, Last Will & session
Retained messages
Sætter du retain-flaget på en PUBLISH, gemmer brokeren den
seneste besked for det topic. Nye subscribers får den med det samme —
uden at vente på næste publish. Perfekt til status = online/offline
eller “nuværende setpunkt”.
Last Will and Testament (LWT)
Ved CONNECT kan klienten registrere en “testament”-besked. Hvis
forbindelsen dør uden DISCONNECT (WiFi drop, strømafbrydelse, crash),
publicerer brokeren testamentet. I jeres Opla-sketch sættes LWT til
demo/opla/status = offline.
// Konceptuelt (PubSubClient):
mqtt.connect(clientId, NULL, NULL,
"demo/opla/status", // will topic
0, // will QoS
true, // will retain
"offline"); // will payload
Clean Session / Persistent Session
Clean Session = true — frisk start. Ingen lagrede subscriptions/QoS-køer.
Demo-browseren bruger clean session (simpelt). Batteridrevne noder,
der kun vågner lejlighedsvis, bruger ofte persistent session.
Keep-alive
Et sekund-interval aftalt i CONNECT. Er der ingen trafik inden for
ca. 1,5 × keep-alive, forventes PINGREQ/PINGRESP — ellers antages
forbindelsen tabt.
Sikkerhed (kort)
Brug TLS på port 8883 i produktion
Username/password eller certifikater på CONNECT
ACL på brokeren: hvem må publish/subscribe hvilke topics?
Undgå åbne brokers på internettet uden auth
08 Live MQTT Demo
Forbind til brokeren og oplev MQTT’s styrker live: fan-out, wildcards,
retain, QoS, Last Will — plus Opla-sensorer og LED-styring.
MQTT Lab
Hver blok nedenfor er sin egen live-demo mod den rigtige broker.
Tryk Forbind øverst, læs forklaringen, og prøv knapperne —
det er samme protokol som Arduino Opla bruger.
01
Decoupling · Many-to-many
Én publish → mange subscribers
I klassisk HTTP kalder afsender ofte hver modtager direkte.
I MQTT sender du kun til et topic. Brokeren finder
alle, der har subscribed — dashboard, mobil, logger osv.
Derfor behøver Arduino Opla ikke kende pensumsiden eller dit
C#-program. Den publicerer; hvem der lytter, er brokerens sag.
Sørg for at du er forbundet
Tryk Publish “alarm”
Se de tre “apps” lyse op — samme besked, tre filtre
Hvorfor det er fedt til IoT: du kan tilføje nye forbrugere uden at ændre firmware på sensoren.
demo/lab/alarm
⇣ broker fan-out
Dashboard demo/lab/#
Mobil-app demo/lab/alarm
Logger demo/+/alarm
Afventer publish…
02
Topics · Filtrering
Wildcards live
Topics er hierarkiske stier. Ved subscribe kan du bruge wildcards:
+ — præcis ét niveau (fx ethvert rum, men kun temp)
# — alt under det punkt (hele undertræet)
Eksakt topic — kun den ene kanal
Det er sådan en C#-logger kan lytte på skole/+/temp
uden at kende hvert enkelt rum-ID på forhånd.
Vælg et filter (+, # eller eksakt)
Publish til forskellige under-topics
Inboxen viser hits — og gule linjer når noget ikke matcher
Prøv: vælg demo/lab/+/temp og publish a/humidity — den skal ikke matche.
Ingen hits endnu — vælg filter og publish
03
State · Late join
Retained messages
Med retain-flaget gemmer brokeren den seneste
besked for et topic. Når en ny klient subscriber, får den
straks den gemte værdi — uden at vente på næste publish.
Perfekt til ting som “nuværende setpoint”, “lampens tilstand”
eller Opla’s demo/opla/status (online/offline).
Skriv en payload og tryk Gem retained
Tryk Simuler sen subscriber — en helt ny MQTT-klient oprettes
Den får værdien med det samme ved subscribe
Ryd retained sender en tom retained besked (MQTT-måden at slette på)
Hvorfor det er fedt til IoT: et dashboard der lige er åbnet, ved med det samme hvad verdens tilstand er.
Broker gemmer—
topic: demo/lab/retained
Modtaget ved connect—
tryk knappen
04
Leveringsgaranti
Quality of Service — 0, 1 og 2
QoS er aftalen mellem klient og broker om, hvor sikker levering skal være.
Flere bekræftelsespakker = mere trafik, men stærkere garanti.
QoS 0 At most once — hurtigst, kan gå tabt
QoS 1 At least once — PUBACK, kan komme dobbelt
QoS 2 Exactly once — fuld handshake, langsomst
Send samme type besked med hvert QoS-niveau
Sammenlign tiden: QoS 0 er “fire and forget”, 1 og 2 venter på ack
Tænk: hvad passer til temp hvert 5. sek vs. en kritisk kommando?
Ved CONNECT kan en klient registrere et testament:
topic + payload. Hvis forbindelsen dør uden pæn DISCONNECT
(WiFi drop, crash, strømafbrydelse), publicerer brokeren det automatisk.
Opla gør det allerede: Last Will sætter demo/opla/status
til offline. Dashboardet behøver ikke gætte — brokeren fortæller det.
Start klient m. LWT — registrerer will = offline
Kill forbindelse — abrupt close → testament udgives
Prøv igen med Pæn DISCONNECT — så udføres testamentet ikke
Læg mærke til: forskellen mellem “kill” og “pæn disconnect” er hele pointeren med LWT.
Ingen LWT-klient
Klar — start en LWT-klient på demo/lab/will (retained).
06
Telemetri + kommandoer
Bidirektionelt på samme forbindelse
MQTT er ikke kun sensor → cloud. Samme åbne socket kan både
modtage telemetri og sende kommandoer
(LED-farve, buzzer). Ingen ekstra HTTP-request per kommando.
Det er derfor Opla både publicerer temp/fugt/lys og subscriber på
demo/opla/cmd/# — web → broker → enhed, med det samme.
Tjek Opla-status nedenfor (kommer fra retained LWT/status)
Åbn Arduino Opla-fanen
Send en RGB-farve eller bip — se resultatet på hardwaren
Én session: keep-alive, QoS og auth gælder begge veje.
Opla ukendt
↑ sensors · ↓ cmd/led · ↓ cmd/buzzer
◈
Arduino Opla
Afventer data
🌡
Temperatur
—
°C
💧
Luftfugtighed
—
%
☀
Lys
—
lux
👆
Seneste knap
—
Styr Opla — 5 RGB LED'er
Send RGB til demo/opla/cmd/led/0 … /4 —
payload fx 255,128,0 eller off