Il protocollo MQTT

Mi serviva un protocollo flessibile ma completo, con poco accoppiamento, per far comunicare sia gli #IOT che creare un'infrastruttura per le notifiche delle mie app.

PUB/SUB

#pubsub Questo design pattern l'ho utilizzato per la prima volta in un workshop javascript alla SUPSI circa una decina di anni fa. Si trattata di sviluppare un'interfaccia web che potesse controllare delle lampadine Phillips Hue e al tempo utilizzai PUP/SUB per mantenere la comunicazione tra i moduli della UI il più disaccoppiato possibile. Ed è proprio questa la parola d'ordine di PUB/SUB: disaccoppiamento. Nel caso della UI javascript il disaccoppiamento può essere totale, un modulo lancia un evento nell'oggetto Window e un altro modulo può ascoltare senza intermediari, mentre in MQTT deve esserci anche un server che si occupa di orchestrare il tutto.

Gli host

Gli host sono gli apparati che si scambiano i messaggi, ogni messaggio viaggia su dei canali, che in MQTT vengono chiamati Topic. Ogni host può avere contemporaneamente sia il ruolo di publisher che di subscriber, infatti può inviare messaggi su questi topic, oppure rimanere in ascolto su questi canali ricevendone i messaggi, tutto questo conoscendo almeno una sola informazione fondamentale: l'indirizzo del server broker.

Server broker

Possiamo immaginare Pub/sub come un'infrastruttura a stella, in cui al centro vi é il server broker. Lui si occupa di mantenere il registro dei topic creati, di quali host si sono iscritti, accettare gli host e gestire lo scambio dei messaggi.

Il protocollo MQTT

MQTT (Message Queuing Telemetry Transport) è un protocollo di messaggistica leggero e open source progettato per la comunicazione tra dispositivi IoT (Internet of Things) e sistemi software. È stato sviluppato nel 1999 da Andy Stanford-Clark e Arlen Nipper ed è diventato uno standard de facto per la comunicazione IoT grazie alla sua semplicità e flessibilità. Si lo so, dello spiegone non vene frega nulla, by the way ... Una delle caratteristiche principali di MQTT è la sua leggerezza. Infatti il protocollo utilizza un formato binario per i messaggi, che riduce al minimo la quantità di dati trasmessi sulla rete. Inoltre, MQTT supporta la compressione dei dati e l'utilizzo di connessioni persistenti, che consentono di risparmiare banda e ridurre la latenza. Rispetto ad altri protocolli come [[BacNet]] o [[ModBus]], MQTT è molto flessibile: supporta diversi tipi di messaggi oltre al sopracitato binario, come testo o JSON, e può essere utilizzato su diverse reti, come TCP/IP, Wi-Fi e cellulare.

Riassumendo: abbiamo un protocollo che necessita poche risorse, agnostico rispetto all'hardware, supporta TCP/IP e anche JSON. Cosa vogliamo di più?

I messaggi di MQTT

Arrivato a questo punto vi devo confessare una cosa: mi sono trasformato in un kamikaze e mi sono scritto un servizio broker da zero con python. Potrebbe sembrare una perdita di tempo (anche perché ora uso un altro broker), ma questo mi è servito per comprendere fino al livello più basso come venivano scambiati i messaggi. Infatti, per rimanere leggero, MQTT utilizza un proprio pacchetto in cui le informazioni sono codificate in binario.

Ogni pacchetto MQTT è composto da tre parti principali:

Fixed Header (Intestazione Fissa)

Presente in tutti i pacchetti MQTT. Contiene il Tipo di Pacchetto, flag di controllo e la lunghezza del pacchetto

Variable Header (opzionale)

Contiene informazioni specifiche per il tipo di pacchetto (es. topic, identificatore del pacchetto)

Payload (opzionale)

Contiene il contenuto vero e proprio del messaggio (es. un JSON con i dati del sensore).

Andando a fondo nella messaggistica potremmo perderci, quindi scriverò un articolo di approfondimento. Quindi direi di rimanere per ora in superficie, vedendo come opera in pratica

Come si scambia i messaggi il protocollo MQTT

MQTT ha 14 tipi di pacchetti: alcuni per la sottoscrizione, altri per l'invio di messaggi, ma la maggior parte sono diagnostici.

  1. CONNECT: stabilisce una connessione con il broker.
  2. CONNACK: conferma la connessione.
  3. PUBLISH: invia un messaggio a un topic.
  4. PUBACK: conferma la ricezione di un messaggio pubblicato.
  5. SUBSCRIBE: richiede di iscriversi a uno o più topic.
  6. SUBACK: conferma l'iscrizione a un topic.
  7. UNSUBSCRIBE: richiede di disiscriversi da un topic.
  8. UNSUBACK: conferma la disiscrizione.
  9. PINGREQ: verifica la connessione.
  10. PINGRESP: risponde alla richiesta di verifica.
  11. DISCONNECT: chiude la connessione.

I pacchetti operano anche con 3 livelli di QoS che determina o meno se il client debba aspettarsi un feedback di ricezione.

In pratica l'host manda un pacchetto CONNECT al server e, dopo l'acknowledge, potrà sia pubblicare un suo topic, con PUBLISH, sia mettersi in ascolto, con SUBSCRIBE, su di un'altro topic.

Ora possiamo passare a vedere come [[Implementare un'infrastruttura MQTT]]