MQTT è un protocollo di messaggistica leggero basato su publish/subscribe. Dispositivi e applicazioni si collegano a un unico server, il broker, e pubblicano messaggi su topic con un nome come site/dub01/mdb1/main-incomer. Ogni client iscritto a quel topic riceve il messaggio dal broker. Publisher e subscriber non si indirizzano mai a vicenda, quindi un contatore, una dashboard e una piattaforma cloud possono condividere dati senza conoscersi. MQTT funziona su TCP sulla porta 1883, o su TLS sulla porta 8883, e la sua intestazione fissa è di soli due byte. Poiché ogni dispositivo si collega in uscita al broker e un numero qualsiasi di sistemi può iscriversi agli stessi dati, è diventato il protocollo più diffuso per inviare via Internet la telemetria di sensori e contatori.
Come funziona MQTT
| Elemento | Che cosa fa | Esempio |
|---|---|---|
| Broker | Accetta le connessioni, verifica i permessi e inoltra ogni messaggio ai subscriber corrispondenti | Eclipse Mosquitto su un server, o un servizio IoT in cloud |
| Client | Qualsiasi dispositivo o applicazione che si collega al broker per pubblicare, iscriversi o entrambe le cose | Un gateway, una dashboard, un processo che scrive in un database |
| Topic | Un indirizzo testuale con livelli separati da / | site/dub01/mdb1/main-incomer |
| Messaggio | Un topic, un payload fino a 256 MB e alcuni flag | Un oggetto JSON con le letture |
| Sottoscrizione | Un filtro di topic, con caratteri jolly facoltativi | site/dub01/# |
| QoS | Il livello di conferma su ogni tratta | 0, 1 o 2 |
| Sessione | Ciò che il broker ricorda delle sottoscrizioni e dei messaggi non consegnati di un client | Mantenuta alla riconnessione se il client lo chiede |
Un client apre una connessione TCP verso il broker e invia CONNECT con il proprio identificativo, le credenziali e un intervallo di keep-alive. Il broker risponde CONNACK. Un publisher invia poi pacchetti PUBLISH; un subscriber invia SUBSCRIBE con uno o più filtri di topic, e da quel momento il broker gli invia ogni PUBLISH corrispondente. Se nell'intervallo di keep-alive non passa alcun pacchetto, il client invia PINGREQ, e il broker chiude una connessione che resta muta per una volta e mezza l'intervallo.
Poiché ogni client apre una connessione in uscita verso il broker, il gateway di un sito non ha bisogno di porte aperte in ingresso. È il principale motivo pratico per cui MQTT ha sostituito i protocolli a polling per inviare i dati fuori dal sito.
Topic e caratteri jolly
I topic sono stringhe che distinguono maiuscole e minuscole. Un client non crea un topic: ci pubblica, e il broker instrada il messaggio verso ogni sottoscrizione corrispondente. Una sottoscrizione può usare due caratteri jolly:
| Filtro | Corrisponde a | Non corrisponde a |
|---|---|---|
site/dub01/mdb1/+ | site/dub01/mdb1/main-incomer, site/dub01/mdb1/chiller-2 | site/dub01/mdb1/chiller-2/alarm |
site/dub01/# | Ogni topic sotto site/dub01, a qualsiasi profondità | site/cork02/mdb1/main-incomer |
site/+/mdb1/main-incomer | Quel contatore in ogni sito | Altri contatori |
+ sostituisce un livello e # tutto il resto dell'albero, quindi deve stare in fondo. I topic che iniziano con $ sono riservati al broker, come $SYS/ per le sue statistiche, e un filtro che inizia con un carattere jolly non li include.
Progetta l'albero dei topic prima che il primo dispositivo pubblichi, perché ogni subscriber e ogni regola di accesso dipende da esso. Un buon albero va dall'ambito più ampio al più stretto (organizzazione, sito, quadro, dispositivo, poi il tipo di messaggio), mette ogni dispositivo in un solo punto ed esclude i valori che cambiano, come una lettura, un timestamp o un numero di sessione. Separa i topic di telemetria, stato e comando, così da concedere il permesso di scrittura solo dove serve.
QoS, messaggi retained e last will
MQTT ha tre livelli di consegna. Valgono per una tratta alla volta: dal publisher al broker e dal broker a ogni subscriber.
| QoS | Consegna | Pacchetti su una tratta | Uso tipico |
|---|---|---|---|
| 0 | Al massimo una volta | PUBLISH | Letture frequenti, dove un valore perso viene presto sostituito |
| 1 | Almeno una volta, duplicati possibili | PUBLISH, PUBACK | Letture di contatori ed eventi che devono arrivare |
| 2 | Esattamente una volta su quella tratta | PUBLISH, PUBREC, PUBREL, PUBCOMP | Raro; costa quattro pacchetti per messaggio |
Un messaggio retained viene conservato dal broker come ultimo valore del suo topic e inviato subito a ogni nuovo subscriber: è adatto allo stato di un dispositivo, ma può consegnare una lettura obsoleta. Il last will è un messaggio che il broker pubblica per un client la cui connessione cade senza un DISCONNECT regolare: è così che un subscriber scopre che un gateway è offline. La guida a QoS e messaggi retained MQTT tratta entrambi nel dettaglio, insieme alla scadenza dei messaggi e alle sessioni persistenti.
Porte e sicurezza di MQTT
| Porta | Trasporto | Uso |
|---|---|---|
| 1883 | TCP | MQTT senza cifratura: solo su una rete locale chiusa |
| 8883 | TLS su TCP | MQTTS: la scelta normale su Internet o su una rete condivisa |
| 443 (o un'altra) | WebSocket su TLS | Browser e reti che consentono solo HTTPS |
MQTT di per sé ha solo un campo per nome utente e password. Cifratura, identità del server e certificati client vengono da TLS, e il controllo degli accessi dalle regole del broker su quale client può pubblicare o iscriversi a quali topic. La guida a MQTTS spiega i certificati, la verifica del nome del server e come provare una connessione TLS dalla riga di comando.
MQTT 3.1.1 e MQTT 5 a confronto
MQTT è nato nel 1999 per la telemetria degli oleodotti via satellite. OASIS ha pubblicato MQTT 3.1.1 come standard nel 2014, diventato ISO/IEC 20922 nel 2016, e MQTT 5.0 nel 2019. La maggior parte dei broker supporta entrambe le versioni, e molti dispositivi parlano ancora solo la 3.1.1.
| MQTT 3.1.1 | MQTT 5.0 | |
|---|---|---|
| Conferme | Successo o pochi codici CONNACK | Un codice di motivo su ogni conferma, rifiuti compresi |
| Sessione | Clean session sì o no | Intervallo di scadenza della sessione |
| Durata di un messaggio | Nessuna | Intervallo di scadenza del messaggio |
| Metadati | Nessuno | Proprietà utente, tipo di contenuto, indicatore di formato |
| Ripartizione del carico | Dipende dal broker | Sottoscrizioni condivise ($share/group/topic) |
| Banda | Il topic completo ogni volta | Gli alias dei topic sostituiscono un topic lungo con un numero |
| Richiesta e risposta | Per convenzione | Topic di risposta e dati di correlazione |
| Controllo di flusso | Nessuno | Receive Maximum e dimensione massima del pacchetto |
Per la telemetria, le funzioni più utili di MQTT 5 sono i codici di motivo, perché il client vede che il broker ha rifiutato un messaggio, e la scadenza dei messaggi, perché un comando ritardato da un'interruzione viene scartato invece di essere eseguito in ritardo.
Payload: JSON, Sparkplug B e il contratto dei dati
MQTT trasporta byte e non dice nulla del loro significato. La maggior parte delle piattaforme energetiche si aspetta JSON, per esempio:
{"ts":"2026-10-28T09:15:00Z","kW":184.2,"kWh":1532871.4,"V1":231.4,"PF":0.94,"q":"good"}Il topic dice di quale contatore si tratta; il payload porta l'ora della misura, i valori e un indicatore di qualità. Le unità e il significato di ogni chiave devono essere scritti e concordati con ogni subscriber: kW o W, energia prelevata o netta, l'ora del contatore o l'ora in cui il gateway ha ricevuto il valore. È questo accordo, non il supporto di MQTT, a far lavorare insieme due sistemi. La guida all'interoperabilità elenca che cosa deve fissare un contratto dei dati, e la guida a ora della misura e ora di arrivo spiega perché l'ora della misura va nel payload.
Sparkplug B, specifica della Eclipse Foundation diffusa nei sistemi industriali, fissa invece il contratto. I topic seguono spBv1.0/<group>/<message type>/<edge node>/<device>, il payload è binario in Protocol Buffers e ogni nodo edge pubblica un certificato di nascita con le sue metriche e un certificato di morte (tramite il last will) quando si disconnette. Un subscriber può così scoprire i dispositivi e segnare i dati come obsoleti senza alcun accordo specifico, al prezzo di un formato binario che richiede un client compatibile con Sparkplug per essere letto.
Esempio pratico: quanti dati consuma la telemetria MQTT?
Cinquanta contatori pubblicano ogni 10 secondi il messaggio JSON qui sopra con QoS 1. Il payload è di 88 byte e il topic di 28 byte, quindi ogni pacchetto PUBLISH è di circa 122 byte. TLS aggiunge circa 22 byte per record e TCP e IP circa 52 byte per segmento: ogni messaggio occupa sulla linea circa 200 byte.
| Un messaggio per contatore | Un messaggio per sito | |
|---|---|---|
| Messaggi al giorno | 50 × 8.640 = 432.000 | 8.640 |
| Dimensione di ogni messaggio sulla linea | circa 200 byte | circa 3.900 byte (50 letture) |
| Dati inviati al giorno | circa 86 MB | circa 34 MB |
| Dati al mese | circa 2,6 GB | circa 1 GB |
Il messaggio per sito porta le 50 letture in un array JSON di circa 3.650 byte (circa 73 byte per contatore, con un solo timestamp per tutto il messaggio), più topic e intestazioni, che TCP suddivide in tre segmenti.
Nel primo caso i PUBACK di ritorno aggiungono circa altri 30 MB al giorno. Su una linea fissa nulla di tutto questo conta; su una SIM cellulare decide il piano dati. Raggruppare le letture di un sito in un solo messaggio, o inviare solo le variazioni, riduce l'overhead. Il calcolatore della domanda per intervallo aiuta a scegliere un intervallo che risponda ancora alla domanda a cui servono i dati.
MQTT a confronto con altri protocolli
| MQTT | HTTP (REST) | Modbus TCP | OPC UA | |
|---|---|---|---|---|
| Modello | Publish/subscribe tramite un broker | Richiesta e risposta | Richiesta e risposta, il client interroga | Client e server, con sottoscrizioni; esiste anche una modalità publish/subscribe |
| Chi si collega | Ogni client si collega in uscita al broker | Client verso server | Client verso ogni dispositivo | Client verso ogni server |
| Modello dei dati | Nessuno: payload libero | Nessuno: lo definisce l'API | Registri numerati | Nodi tipizzati con unità e stato |
| Uso tipico | Dal sito al cloud, dal dispositivo alla piattaforma | Invii occasionali, API web | Contatori e regolatori in sito | Sistemi d'impianto e SCADA |
MQTT è di solito il collegamento tra un sito e una piattaforma, mentre Modbus, BACnet e OPC UA leggono i dispositivi in sito. Il confronto tra OPC UA, Modbus e MQTT li mette a confronto per i progetti industriali, e Che cos'è Modbus? spiega il lato a polling.
MQTT con EpiSensor
Edge sul Gateway ZGW-20 legge i dispositivi Zigbee, Modbus, BACnet e LoRaWAN del sito, registra ogni lettura con l'ora della misura e pubblica verso il broker di una piattaforma come client MQTT, di norma via MQTTS sulla porta 8883 con un certificato client. Pubblica con QoS 1 e conserva le consegne fallite in una coda locale, che ripropone con i timestamp originali quando il broker torna disponibile. Topic e payload seguono il contratto della piattaforma, e Collegare Edge alla propria piattaforma mostra i modi in cui Edge invia i dati.
Domande frequenti
A che cosa serve MQTT?
MQTT trasporta messaggi piccoli e frequenti tra dispositivi e applicazioni: letture di sensori e contatori, cambi di stato e comandi. Si usa nel monitoraggio energetico degli edifici, nella telemetria industriale, nel tracciamento dei veicoli e nella domotica, perché basta una connessione per dispositivo e l'overhead del protocollo è di pochi byte per messaggio.
Che cos'è un broker MQTT?
Il broker è il server al centro di MQTT. I client si collegano a esso, pubblicano messaggi sui topic e si iscrivono ai topic. Il broker verifica i permessi di ogni client, mantiene le sessioni e i messaggi retained e inoltra ogni messaggio a tutti i client con una sottoscrizione corrispondente. Eclipse Mosquitto, EMQX e HiveMQ sono broker diffusi, e i grandi servizi IoT in cloud ne includono uno.
Quale porta usa MQTT?
La porta TCP 1883 per MQTT senza cifratura e la porta TCP 8883 per MQTT su TLS (MQTTS). Entrambe sono registrate presso la IANA. MQTT su WebSocket non ha una porta fissa; spesso usa la 443 dietro un server web, il che aiuta quando un firewall consente solo HTTPS.
MQTT usa TCP o UDP?
MQTT funziona su TCP, o su un altro trasporto che consegna i byte in ordine e senza perdite, come TLS o WebSocket. Un protocollo separato, MQTT-SN, è pensato per le reti di sensori e può funzionare su UDP.
Qual è la differenza tra MQTT e HTTP?
HTTP funziona a richiesta e risposta: un client interroga un server e attende la risposta, e ogni dato richiede una nuova richiesta. MQTT tiene aperta una connessione e il broker spinge ogni messaggio verso i subscriber appena arriva. Per letture piccole e frequenti MQTT usa meno banda e consegna prima le variazioni; HTTP è più semplice per invii occasionali e per sistemi che offrono solo un'API REST.
Qual è la differenza tra MQTT 3.1.1 e MQTT 5?
MQTT 5 mantiene lo stesso modello e aggiunge codici di motivo su ogni conferma, scadenza di messaggi e sessioni, proprietà utente, sottoscrizioni condivise, alias dei topic e topic di risposta. Un broker che supporta MQTT 5 accetta ancora i client MQTT 3.1.1, quindi le due versioni convivono spesso.
Che cos'è Sparkplug B?
Sparkplug è una specifica della Eclipse Foundation che aggiunge a MQTT uno spazio dei nomi dei topic fisso, un payload binario e messaggi di nascita e morte. Un subscriber può così scoprire le metriche di ogni nodo edge e sapere quando i suoi dati sono obsoleti. MQTT da solo non definisce nulla di tutto questo.