Scelta del protocollo appropriato per l'applicazione IoT


12

Abbiamo al lavoro uno scenario IoT in cui il dispositivo cosa / vincolo invia la sua posizione GPS a intervalli regolari a un determinato server. Il dispositivo vincolato è una scheda simile ad Arduino che è alimentata a batteria e utilizza uno scudo GSM / SIM per la connettività. Questi sono i nostri obiettivi di progettazione:

  • Massimizzare la durata della batteria
  • Riduzione al minimo del trasferimento di dati

A scopo di test abbiamo utilizzato HTTP che genera messaggi intorno ai 500 byte, ma è tempo di utilizzare un protocollo più appropriato per la trasmissione dei dati. Alcune delle caratteristiche del trasferimento dei dati sono queste:

  • Il payload è piuttosto piccolo, normalmente meno di 50 byte (abbastanza lontano dai tipici MTU, cioè tutto dovrebbe rientrare in un pacchetto IP)
  • I dati devono essere inviati circa una volta al minuto . Una certa varianza non è critica.
  • Va bene perdere alcuni messaggi
  • In questo momento, il dispositivo non ha bisogno di alcun tipo di risposta dal servizio r (tuttavia, ciò potrebbe cambiare in futuro). Né il server deve iniziare alcuna conversazione con i dispositivi.

Finora abbiamo pensato a queste possibilità:

  • Protocollo personalizzato su TCP . Ciò eliminerebbe le intestazioni HTTP rendendo il messaggio 10 volte più piccolo. Questo è il nostro approccio affidabile / conservativo.
  • Protocollo personalizzato su UDP . Dal momento che UDP ha intestazioni più piccole e nessun sovraccarico per l'affidabilità, ci aspettiamo di essere abbastanza efficienti. Come commentato, perdere un messaggio qui o non c'è preoccupazione ... tuttavia, potrebbero esserci altri problemi con la non affidabilità di cui non siamo a conoscenza.
  • MQTT (standard su TCP): con quasi nessun sovraccarico esistente rispetto a TCP, anche questa potrebbe essere un'opzione ... tuttavia, non abbiamo troppa esperienza con la tecnologia GSM / SIM e non sappiamo come una connessione MQTT continua funzionerebbe in questo modo e se la banda heartbeat della connessione valga la pena per un tale trasferimento di dati a bassa frequenza.
  • CoAP (standard su UDP): sembra anche promettente. Solo 4 byte di sovraccarico per le intestazioni e il funzionamento su UDP. Vi sono tuttavia rischi sconosciuti di UDP.

Qualcuno può dare qualche suggerimento? Grazie in anticipo.


1
@RichardChambers in questo scenario, l'affidabilità non è così importante. Possiamo permetterci di perdere alcuni pacchetti qui o là. Acking non è necessario. Penso che lavorare sull'affidabilità su UDP non abbia molto senso, ecco a cosa serve TCP.
bgusach,

1
Non reinventerei la ruota progettando un protocollo personalizzato. Un google di CoAP vs. MQTT ti darà più considerazioni. Hai bisogno di una soluzione a prova di futuro, ad es. gestire requisiti più severi in futuro (garanzie di perdita, tempi di risposta, interoperabilità, ecc.)? I dispositivi sono NAT? Esiste un raggruppamento di dispositivi dietro i gateway? Molte incognite ...
Gambit Support,

Risposte:


6

Alcuni pensieri sulla mia esperienza con TCP, UDP e MQTT e alcune risorse aggiuntive da rivedere.

Con UDP ho riscontrato il problema del fallimento silenzioso in cui un'applicazione su un nodo di rete, il client, vede solo alcuni dei messaggi UDP che sono stati inviati. Ci sono troppi motivi per cui il traffico di rete può andare storto. Il problema con UDP è che i pacchetti possono essere scartati praticamente ogni volta che uno qualsiasi dei nodi nel percorso di rete tra produttore di pacchetti e consumatore di pacchetti garantisce. Vedi argomento Wikipedia Perdita di pacchetti .

La domanda è qual è il tuo tasso di perdita in qualunque contesto di rete attuale. Quindi, se si tratta di comunicazione all'interno di una LAN o sottorete, il tasso di perdita potrebbe essere basso. Su una WAN o su Internet il tasso di perdita potrebbe essere piuttosto elevato. I pacchetti UDP vengono scartati per una serie di motivi e instradati, tuttavia le condizioni della rete consentono tale decremento del conteggio dei hop. L'invio di pacchetti nel grande vuoto senza responsabilità lascia aperta la possibilità di guasti silenziosi.

Sembra che nel tuo caso basterebbe solo un semplice riconoscimento con ritrasmissione dopo un timeout senza ricevere un riconoscimento.

Ho fatto messaggi XML su una connessione TCP mantenuta e ha funzionato benissimo. Avevo un livello che consegnava messaggi completi ciascuno in un buffer al livello applicazione da gestire. Ho usato XML per impacchettare il messaggio con un tag iniziale XML per l'inizio del messaggio e un tag finale XML per sapere quando era stato ricevuto l'intero messaggio.

TCP ha alcune caratteristiche come l'ordine sequenziale dei pacchetti, nessuna ripetizione, ed essendo un meccanismo di trasporto connesso significa che sai se l'altra estremità scompare o no, anche se potrebbe volerci un po 'di tempo per scoprirlo. La connessione e la disconnessione possono comportare ritardi ma non onerosi in condizioni normali sebbene le condizioni di rete possano rallentare il throughput TCP.

MQTT è un protocollo che viene trasportato da un livello di trasporto di rete, normalmente TCP. MQTT utilizza un modello di pubblicazione / sottoscrizione, quindi non è presente alcun archivio di messaggi. Pertanto, quando un editore pubblica un messaggio se l'utente non è collegato al momento, quando si connette, non vedrà il messaggio. MQTT è praticamente in tempo reale, suppongo che sia la parte della telemetria dell'acronimo. Mi piace MQTT per piccoli messaggi e ho fatto alcuni esperimenti con il payload JSON tramite MQTT usando Mosquitto. Vedi questo articolo Consegna affidabile dei messaggi con Mosquitto (MQTT) con una panoramica di MQTT e della qualità del servizio. E vedere questo breve articolo con i link a risorse tra cui un'applicazione di esempio degli oggetti - MQTT Pubblica e Subscriber codice C .

I miei esperimenti con MQTT utilizzando il testo JSON e un database SQLite3 nell'abbonato per archiviare i messaggi sono su https://github.com/RichardChambers/raspberrypi/tree/master/mqtt sebbene l'origine sia in C ed è piuttosto disordinata.

Ecco un protocollo Internet n. 144 di 13 minuti : CoAP vs MQTT, Network Sniffing e preparazione per IKEA Tradfri Hacking . Questo è un articolo interessante su CoAP, Constrained Application Protocol: CoAP è il protocollo "moderno" di IoT . C'è questa sintesi di CoAP:

I primi utenti concordano sul fatto che il protocollo di applicazione vincolata funziona molto bene per reti e dispositivi vincolati. Qualcosa di non molto noto: "Su una rete wireless molto congestionata - Wi-Fi o cellulare - CoAP può continuare a funzionare laddove un protocollo TCP (Transmission Control Protocol) come MQTT non riesce nemmeno a completare un handshake, "Disse Vermillard.

Questo perché a differenza della maggior parte degli altri protocolli IoT, CoAP è basato su UDP. In altre parole, significa che nessun handshake di protocollo o correzione degli errori riscontrati con TCP. "CoAP potrebbe non essere affidabile come HTTP o garantire la consegna di messaggi come MQTT, ma è estremamente veloce", ha osservato Matthieu. "Se stai bene con alcuni messaggi non ricevuti, puoi inviare molti più messaggi nello stesso lasso di tempo."

Ce ne sono anche alcuni altri come AMQP, STOMP e CBOR. Consulta il sito Web standard CBOR , nonché questa tesi, implementazione e valutazione del protocollo CBOR . Vedi questo articolo, Scelta del protocollo di messaggistica: AMQP, MQTT o STOMP che confronta e contrappone AMQP, MQTT e STOMP e termina con una nota sul broker RabitMQ:

Si spera che questo possa aiutare molti a iniziare a esplorare la minestra del protocollo là fuori per ciascuno dei casi d'uso. Poiché è comune per le aziende avere molte applicazioni con esigenze diverse, è certamente possibile che tu abbia bisogno di tutti e tre i broker in diverse applicazioni. È qui che entra in gioco un solido broker multiprotocollo, poliglotta come RabbitMQ, poiché può inviare STOMP, MQTT o AMQP e ottenere uno degli altri. Non è necessario essere bloccati da uno di questi protocolli: tutti e tre sono supportati dal broker RabbitMQ, rendendolo la scelta ideale per l'interoperabilità tra le applicazioni. L'architettura del plug-in consente inoltre a RabbitMQ di evolversi per supportare versioni aggiuntive o aggiornate di questi protocolli in futuro.

Questo pacchetto di condivisione di diapositive di circa 60 diapositive fa un confronto e un contrasto tra quattro diversi protocolli IoT, esaminando le esigenze di due diversi gruppi IoT, i consumatori e l'industria, che hanno esigenze diverse di affidabilità e robustezza. Qual è lo standard di messaggistica giusto per l'IoT? .


4

Sembra un'applicazione perfetta per UDP: topologia client-server (pub / sub non richiesta), tollerante alla perdita di pacchetti e grandi lacune tra le trasmissioni di pacchetti singoli significano che l'arrivo fuori servizio non è un problema.

I risparmi nella creazione della connessione e nell'overhead dei pacchetti funzioneranno bene a tuo favore.

Hai solo bisogno di mitigare il problema del fallimento silenzioso. Molti modi per farlo, ma il mio suggerimento sarebbe di far rispondere il server ogni volta che riceve pacchetti x (es. 10). In questo modo il cliente sa quanti dei suoi pacchetti stanno attraversando e se è al di sotto di una soglia può aumentare la frequenza delle trasmissioni per contrastare la perdita di pacchetti. Se non passa nulla, TCP non aiuta comunque, quindi è meglio mettere il client in modalità di emergenza fino a quando la condizione non viene cancellata.

La perdita di pacchetti UDP su Internet non è generalmente elevata, e se lo è di solito è un fenomeno transitorio. Il GSM fornisce un po 'di buffering e valutazione del segnale radio, quindi fornisce comunque una certa tolleranza al rumore spurio.


4

Sei costretto esternamente a utilizzare GSM / SIM?

Un'alternativa potrebbe essere quella di utilizzare una rete LoRa che:

  • sono altamente ottimizzati per piccoli carichi utili
  • sono progettati per un consumo minimo di energia (e quindi la durata massima della batteria)
  • sono a lungo raggio dal design
  • avere classi di connessione (sempre attive, riconosciute, non riconosciute)
  • avere finestre di download programmate (ad es. per aggiornamenti del firmware o ACK RX)

È possibile collegarsi a un'infrastruttura LoRa di comunità o commerciale esistente nella maggior parte dei paesi, oppure è possibile distribuire i propri hub LoRa se ciò fosse più appropriato.

Esiste uno sviluppo attivo a livello globale e una facile disponibilità di scudi di prototipazione (ad esempio per Arduino).


1
Una volta al minuto, come indicato nella domanda, è troppo frequente per adattarsi agli intervalli di trasmissione del nodo LoRa consigliati.
Chris Stratton,

1
Accetto 1 minuto è troppo spesso. Anche se @bgusach non menziona l'applicazione. Se il payload può essere codificato binario per ridurne le dimensioni e se è utilizzabile un intervallo di 3-5 minuti (o anche 10min), potrebbe essere l'ideale. Ad ogni modo, solo un suggerimento in quanto noto che non era stato precedentemente menzionato nelle risposte.
BrendanMcL

1
Sì, se sto leggendo bene, qualcosa come 50 byte a intervalli di quattro minuti potrebbe a malapena adattarsi; ma ciò richiede una verifica, potrebbe essere facilmente disattivato di almeno un fattore due.
Chris Stratton,

1
Interessante, ma siamo vincolati da GSM / SIM (questo è destinato a essere un bene per il consumatore, qualcosa che può essere acquistato e utilizzato ovunque senza alcuna infrastruttura tranne la rete telefonica).
bgusach,

3

Preferirei una risposta HTTP minima con i dati JSON ... una risposta HTTP può essere molto al di sotto del trasferimento HTTP a 500 byte e tu rimani compatibile con molti client per le applicazioni web RESTful.

Un messaggio HTTP minimo (ad es. Con risultato JSON) con dati HTTP di circa 130 byte è simile a:

HTTP/1.1 200 OK
Server: ProprietaryAndroid
Connection: close
Content-Type: application/json
{
  "lat": "42.00000",
  "long": "10.00000"
}

se vuoi semplicemente INVIARE i dati dalla tua app al server, puoi semplicemente usare un HTTP GET dove imposti lat / long come parametri URL. La richiesta contiene ancora meno dati della risposta.

GET /?lat=42.00000&long=10.0000 HTTP/1.1
Host: 192.168.0.2 
User-Agent: Proprietary
Accept: */* 
Connection: close

7
Grazie per la tua risposta, ma non vedo il tuo punto con la risposta HTTP. Vogliamo sbarazzarci dell'intero protocollo HTTP per salvare il trasferimento dei dati. E per di più, usare GETper modificare le risorse è il Wrong Thing™da fare
bgusach il

Concordo con te dal punto di vista architettonico che altri verbi come POST (come verbo universale) sono nel frattempo più comuni nelle API REST. Dipende dal livello di maturità in cui stai sviluppando l'API REST. Volevo solo mostrare come ridurre al minimo un HTTP, pur mantenendo i vantaggi di una facile impl e della compatibilità con i framework esistenti (client e server), e allo stesso tempo mantenendo la leggibilità umana. Rispondere con un campione di risposta era confuso ... Se vuoi INVIARE i dati, ovviamente useresti un messaggio POST o GET - in caso di POST, con il contenuto json che ho mostrato nel mio primo campione.
Christoph Bimminger,

3

Non esiste un protocollo "migliore". Solo molti compromessi da considerare:

  • I tuoi dispositivi saranno su reti casuali con porte casuali bloccate? In tal caso, potrebbe essere meglio utilizzare HTTPS.

  • Se invii UDP, puoi sempre inviare le ultime N misurazioni ogni volta, in modo che la perdita di pacchetti piccoli venga ignorata. Puoi anche inviare un pacchetto ACK, trasformando UDP in un protocollo affidabile. (La maggior parte dei protocolli su UDP lo fa.)

  • I tuoi clienti si preoccuperanno se i loro dati sono esposti senza crittografia? Ai tuoi clienti importa se gli hacker possono inserire dati errati in quelle connessioni non crittografate? (In tal caso, potresti desiderare la crittografia.)

  • Cosa succede se qualcuno annusa il tuo protocollo e manipola i dati? È possibile impedire a un dispositivo di sovrascrivere i dati per un altro?

  • Quanti dispositivi avrai il massimo? Come hai intenzione di gestire tutti questi dispositivi? Come hai intenzione di indirizzare i dati verso dove devono andare? Come gestite la manutenzione e gli aggiornamenti della vostra infrastruttura server? Se non hai esperienza, probabilmente stai sopravvalutando la tua capacità di gestire molte connessioni simultanee. Potrebbe essere meglio esternalizzare a un fornitore (e utilizzare i loro protocolli, come AWS IoT).


3

Abbiamo un test esatto che confronta la velocità di trasmissione HTTP vs MQTT, vedi test2 , nel tuo scenario attuale MQTT ti porterà 50 volte meno traffico (e batteria) rispetto a HTTP.

Non c'è praticamente alcuna differenza tra MQTT e TCP semplice (nella dimensione del messaggio). Direi persino che non c'è praticamente alcuna differenza tra TCP semplice e messaggio binario e JSON nel payload MQTT. In tal modo è molto più conveniente utilizzare MQTT + JSON e fare affidamento su queste tecnologie per la consegna e la rappresentazione dei dati. Basta nominare le chiavi più o meno brevi.

Per quanto riguarda UDP, se la trasmissione avviene una volta al minuto, è preferibile utilizzare TCP. Se la trasmissione avviene una volta ogni 10-20 minuti o più, è possibile considerare UDP come soluzione più efficace per traffico / batteria. Se proverai a sviluppare il proprio protocollo con ACK, ti consiglio di usare MQTT o TCP e concentrarti solo sul tuo business case.

In generale, più semplice viene implementato, migliori risultati si possono ottenere nel minor tempo possibile. Se fossi in te, in quel caso farei meglio a testare UDP + con il proprio formato binario e MQTT + JSON e selezionarne uno. O anche appena iniziato da MQTT + JSON e poi pensa se va bene per il mio caso.


1
Citerò qui alcune parole contro l'UDP. Manteniamo un grande sistema di gestione della flotta SaaS GPS (più di 1 milione di veicoli connessi) con clienti in oltre 100 paesi in tutto il mondo. E recentemente abbiamo scoperto che i provider di servizi Internet con sede negli Stati Uniti stanno bloccando i pacchetti UDP che escono dagli Stati Uniti per qualche motivo, anche per le applicazioni M2M. È iniziato alcuni mesi fa, ma è molto doloroso, quindi ti consiglio di selezionare il protocollo basato su TCP (MQTT) e fare affidamento sugli standard globali. Un giorno e in alcuni paesi sarai persino costretto a utilizzare MQTT su socket Web per mantenere la connessione. Solo un piccolo consiglio.
shal
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.