Auswahl eines geeigneten Protokolls für die IoT-Anwendung


12

Wir arbeiten an einem IoT-Szenario, in dem das Thing / Constrained Device seine GPS-Position in regelmäßigen Abständen an einen bestimmten Server sendet. Das eingeschränkte Gerät ist eine Arduino-ähnliche Karte, die batteriebetrieben ist und ein GSM / SIM-Schild für die Konnektivität verwendet. Das sind unsere Designziele:

  • Maximierung der Akkulaufzeit
  • Minimierung der Datenübertragung

Zu Testzwecken haben wir HTTP verwendet, was zu Nachrichten mit etwa 500 Byte führte. Es ist jedoch an der Zeit, ein besser geeignetes Protokoll für die Datenübertragung zu verwenden. Einige der Merkmale der Datenübertragung sind folgende:

  • Die Nutzlast ist ziemlich klein, normalerweise weniger als 50 Bytes (ziemlich weit entfernt von den typischen MTUs, dh alles sollte in ein IP-Paket passen)
  • Daten sollten ungefähr einmal pro Minute gesendet werden . Eine gewisse Varianz ist nicht kritisch.
  • Es ist in Ordnung, einige Nachrichten zu verlieren
  • Derzeit benötigt das Gerät keinerlei Antwort vom Server (dies könnte sich jedoch in Zukunft ändern). Der Server muss auch keine Konversation mit den Geräten beginnen.

Bisher haben wir über diese Möglichkeiten nachgedacht:

  • Benutzerdefiniertes Protokoll über TCP . Dies würde die HTTP-Header entfernen und die Nachricht zehnmal kleiner machen. Dies ist unser zuverlässiger / konservativer Ansatz.
  • Benutzerdefiniertes Protokoll über UDP . Da UDP kleinere Header und keinen Overhead für die Zuverlässigkeit hat, erwarten wir, dass wir ziemlich effizient sind. Wie bereits erwähnt, besteht der Verlust einer Nachricht hier oder da kein Problem. Es kann jedoch auch andere Probleme mit der Nichtzuverlässigkeit geben, die uns nicht bekannt sind.
  • MQTT (Standard über TCP): Da im Vergleich zu TCP fast kein Overhead vorhanden ist, könnte dies ebenfalls eine Option sein. Wir haben jedoch nicht zu viel Erfahrung mit der GSM / SIM-Technologie und wissen nicht wie Eine kontinuierliche MQTT-Verbindung würde auf diese Weise funktionieren und ob sich die Bandbreite des Verbindungsherzschlags für eine solche niederfrequente Datenübertragung lohnt.
  • CoAP (Standard über UDP): Scheint ebenfalls vielversprechend. Nur 4 Bytes Overhead für die Header und Arbeiten über UDP. Unbekannte Risiken von UDP sind jedoch vorhanden.

Kann jemand einen Hinweis geben? Danke im Voraus.


1
@RichardChambers In diesem Szenario ist die Zuverlässigkeit nicht so wichtig. Wir können es uns leisten, hier oder da einige Pakete zu verlieren. Ackist nicht erforderlich. Ich denke, dass es nicht allzu viel Sinn macht, neben UDP an Zuverlässigkeit zu arbeiten. Dafür ist TCP gedacht.
Bgusach

1
Ich würde das Rad nicht neu erfinden, indem ich ein benutzerdefiniertes Protokoll entwerfe. Ein Google von CoAP vs. MQTT gibt Ihnen weitere Überlegungen. Müssen Sie Ihre Lösung zukunftssicher machen, dh. in Zukunft strengere Anforderungen erfüllen (Verlustgarantien, Reaktionszeit, Interoperabilität usw.)? Sind die Geräte NAT'ed? Gibt es eine Gruppierung von Geräten hinter Gateways? Viele Unbekannte ...
Gambit Support

Antworten:


6

Ein paar Gedanken zu meinen Erfahrungen mit TCP, UDP und MQTT sowie einige zusätzliche Ressourcen, die überprüft werden müssen.

Mit UDP bin ich auf das Problem des stillen Fehlers gestoßen, bei dem eine Anwendung auf einem Netzwerkknoten, dem Client, nur einige der gesendeten UDP-Nachrichten sieht. Es gibt zu viele Gründe, warum der Netzwerkverkehr schief gehen kann. Das Problem mit UDP besteht darin, dass Pakete so gut wie immer verworfen werden können, wenn einer der Knoten im Netzwerkpfad zwischen dem Hersteller von Paketen und dem Verbraucher von Paketen dies rechtfertigt. Siehe Wikipedia-Thema Paketverlust .

Die Frage ist, wie hoch Ihre Verlustrate im aktuellen Netzwerkkontext ist. Wenn es sich also um Kommunikation innerhalb eines LANs oder Subnetzwerks handelt, ist Ihre Verlustrate möglicherweise niedrig. In einem WAN oder über das Internet kann Ihre Verlustrate recht hoch sein. UDP-Pakete werden aus einer Reihe von Gründen verworfen und weitergeleitet, jedoch ermöglichen die Netzwerkbedingungen, dass die Anzahl der Hops verringert wird. Das Versenden von Paketen in die große Leere ohne Verantwortlichkeit lässt die Möglichkeit stiller Fehler offen.

Es klingt so, als würde in Ihrem Fall nur eine einfache Bestätigung mit erneuter Übertragung nach einer Zeitüberschreitung ohne Bestätigung ausreichen.

Ich habe XML-Nachrichten über eine gepflegte TCP-Verbindung erstellt und es hat großartig funktioniert. Ich hatte eine Schicht, die vollständige Nachrichten in einem Puffer an die Anwendungsschicht lieferte, um sie zu verarbeiten. Ich habe XML verwendet, um die Nachricht mit einem XML-Start-Tag für den Anfang der Nachricht und einem XML-End-Tag zu verpacken, um zu wissen, wann die gesamte Nachricht empfangen wurde.

TCP verfügt über einige Funktionen wie die sequentielle Reihenfolge der Pakete, keine Wiederholungen und als verbundener Transportmechanismus wissen Sie, ob das andere Ende verschwindet oder nicht, obwohl es eine Weile dauern kann, bis Sie es herausfinden. Das Verbinden und Trennen kann zu Verzögerungen führen, ist jedoch unter normalen Bedingungen nicht belastend, obwohl die Netzwerkbedingungen dazu führen können, dass der TCP-Durchsatz langsamer wird.

MQTT ist ein Protokoll, das von einer Netzwerk-Transportschicht, normalerweise TCP, transportiert wird. MQTT verwendet ein Publish / Subscribe-Modell, sodass keine Nachricht gespeichert wird. Wenn ein Herausgeber eine Nachricht veröffentlicht, wenn der Abonnent zu diesem Zeitpunkt nicht verbunden ist, wird die Nachricht beim Herstellen der Verbindung nicht angezeigt. MQTT ist so ziemlich in Echtzeit, ich nehme an, darum geht es im Telemetrieteil des Akronyms. Ich mag MQTT für kleine Nachrichten und habe einige Experimente mit JSON-Nutzdaten über MQTT mit Mosquitto durchgeführt. Siehe diesen Artikel Zuverlässige Nachrichtenübermittlung mit Mosquitto (MQTT) mit einem Überblick über MQTT und die Servicequalität. In diesem kurzen Artikel finden Sie Links zu Ressourcen, einschließlich einer Beispielanwendung IoT - MQTT Publish und Subscriber C Code .

Meine Experimente mit MQTT unter Verwendung von JSON-Text und einer SQLite3-Datenbank im Abonnenten zum Speichern von Nachrichten finden Sie unter https://github.com/RichardChambers/raspberrypi/tree/master/mqtt, obwohl sich die Quelle in C befindet und ziemlich chaotisch ist.

Hier ist ein 13-minütiges Video # 144 Internet Protocols: CoAP vs MQTT, Network Sniffing und Vorbereitung auf IKEA Tradfri Hacking . Dies ist ein interessanter Artikel über CoAP, Constrained Application Protocol: CoAP ist das 'moderne' Protokoll von IoT . Es gibt diese Zusammenfassung von CoAP:

Early Adopters sind sich einig, dass das Constrained Application Protocol für eingeschränkte Netzwerke und Geräte sehr gut funktioniert. Etwas nicht so Bekanntes: "In einem sehr überlasteten drahtlosen Netzwerk - Wi-Fi oder Mobilfunk - kann CoAP weiterhin funktionieren, wenn ein auf Transmission Control Protocol basierendes (TCP) Protokoll wie MQTT nicht einmal einen Handshake ausführen kann. "Sagte Vermillard.

Dies liegt daran, dass CoAP im Gegensatz zu den meisten anderen IoT-Protokollen auf UDP basiert. Mit anderen Worten bedeutet dies, dass bei TCP keine Protokoll-Handshakes oder Fehlerkorrekturen auftreten. "CoAP ist möglicherweise nicht so zuverlässig wie HTTP oder garantiert die Zustellung von Nachrichten wie MQTT, aber es ist extrem schnell", bemerkte Matthieu. "Wenn Sie damit einverstanden sind, dass einige Nachrichten nicht empfangen werden, können Sie innerhalb desselben Zeitraums viele weitere Nachrichten senden."

Es gibt einige andere wie AMQP, STOMP und CBOR, die Sie möglicherweise ebenfalls betrachten. Siehe die CBOR-Standardwebsite sowie diese Arbeit, Implementierung und Bewertung des CBOR-Protokolls . Weitere Informationen finden Sie in diesem Artikel, Auswählen Ihres Messaging-Protokolls: AMQP, MQTT oder STOMP , in dem AMQP, MQTT und STOMP verglichen und gegenübergestellt werden und der mit einem Hinweis zum RabitMQ-Broker endet:

Hoffentlich kann dies vielen helfen, die Protokollsuppe für jeden Ihrer Anwendungsfälle zu navigieren. Da Unternehmen häufig viele Anwendungen mit unterschiedlichen Anforderungen haben, ist es durchaus möglich, dass Sie alle drei Broker für unterschiedliche Anwendungen benötigen. Hier kommt ein solider Multiprotokoll-Polyglot-Broker wie RabbitMQ ins Spiel - da er STOMP, MQTT oder AMQP einsenden und einen der anderen herausholen kann. Sie müssen nicht an eines dieser Protokolle gebunden sein - alle drei werden vom RabbitMQ-Broker unterstützt, sodass es eine ideale Wahl für die Interoperabilität zwischen Anwendungen ist. Die Plugin-Architektur ermöglicht es RabbitMQ auch, sich weiterzuentwickeln, um in Zukunft zusätzliche oder aktualisierte Versionen dieser Protokolle zu unterstützen.

Dieses Folienfreigabepaket mit rund 60 Folien bietet einen Vergleich und Kontrast zwischen vier verschiedenen IoT-Protokollen, wobei die Anforderungen von zwei verschiedenen IoT-Gruppen, Consumers und Industrial, berücksichtigt werden, die unterschiedliche Anforderungen an Zuverlässigkeit und Robustheit stellen. Was ist der richtige Messaging-Standard für das IoT? .


4

Klingt nach einer perfekten Anwendung für UDP: Client-Server-Topologie (Pub / Sub nicht erforderlich), tolerant gegenüber Paketverlust und große Lücken zwischen Einzelpaketübertragungen bedeuten, dass das Eintreffen außerhalb der Reihenfolge kein Problem darstellt.

Die Einsparungen beim Verbindungsaufbau und beim Paket-Overhead wirken sich gut zu Ihren Gunsten aus.

Sie müssen nur das Problem des stillen Fehlers abmildern. Viele Möglichkeiten, dies zu tun, aber mein Vorschlag wäre, den Server jedes Mal antworten zu lassen, wenn er x (z. B. 10) Pakete empfängt. Auf diese Weise weiß der Client, wie viele seiner Pakete durchkommen, und wenn er unter einem Schwellenwert liegt, kann er die Übertragungshäufigkeit erhöhen, um dem Paketverlust entgegenzuwirken. Wenn nichts durchkommt, hilft TCP sowieso nicht weiter. Sie sollten den Client also besser in den Notmodus versetzen, bis der Zustand behoben ist.

Der Verlust von UDP-Paketen über das Internet ist im Allgemeinen nicht hoch, und wenn dies der Fall ist, handelt es sich normalerweise um ein vorübergehendes Phänomen. GSM bietet eine gewisse Pufferung und Funksignalbewertung, bietet also ohnehin eine gewisse Toleranz gegenüber Störgeräuschen.


4

Sind Sie extern gezwungen, GSM / SIM zu verwenden?

Eine Alternative kann die Verwendung eines LoRa-Netzwerks sein, das:

  • sind stark für kleine Nutzlasten optimiert
  • sind auf minimalen Energieverbrauch (und damit maximale Akkulaufzeit) ausgelegt
  • sind von Natur aus weitreichend
  • Verbindungsklassen haben (immer aktiviert, bestätigt, nicht bestätigt)
  • geplante Download-Fenster (z. B. für Firmware-Updates oder RX-ACKs)

In den meisten Ländern können Sie sich an eine vorhandene Community- oder kommerzielle LoRa-Infrastruktur anschließen oder Ihre eigenen LoRa-Hubs bereitstellen, wenn dies angemessener ist.

Es gibt eine aktive Entwicklung weltweit und eine einfache Verfügbarkeit von Prototyping-Schilden (zum Beispiel für Arduino).


1
Einmal in der Minute, wie in der Frage erwähnt, ist viel zu häufig, um die empfohlenen Übertragungsintervalle für LoRa-Knoten zu erfüllen.
Chris Stratton

1
Einverstanden 1 min ist zu oft. Obwohl @bgusach die Anwendung nicht erwähnt. Wenn die Nutzdaten binär codiert werden können, um die Größe zu verringern, und wenn ein Intervall von 3 bis 5 Minuten (oder sogar 10 Minuten) verwendet werden kann, ist dies ideal. Wie auch immer, nur ein Vorschlag, da ich feststelle, dass er zuvor in den Antworten nicht erwähnt wurde.
BrendanMcL

1
Ja, wenn ich es richtig lese, könnten etwa 50 Bytes in Intervallen von vier Minuten kaum passen. Aber das muss überprüft werden, es könnte leicht um mindestens den Faktor zwei abweichen.
Chris Stratton

1
Interessant, aber wir sind auf GSM / SIM beschränkt (dies soll ein Konsumgut sein, das überall ohne Infrastruktur außer dem Telefonnetz gekauft und verwendet werden kann).
Bgusach

3

Ich würde eine minimale HTTP-Antwort mit JSON-Daten bevorzugen ... Eine HTTP-Antwort kann weit unter 500 Byte HTTP-Übertragung liegen, und Sie bleiben mit vielen Clients für RESTful-Webanwendungen kompatibel.

Eine minimale HTTP-Nachricht (z. B. mit JSON-Ergebnis) mit ungefähr 130 Byte HTTP-Daten sieht folgendermaßen aus:

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

Wenn Sie nur Daten von Ihrer App an den Server senden möchten, können Sie einfach ein HTTP-GET verwenden, in dem Sie die Parameter lat / long as URL festlegen. Die Anfrage enthält noch weniger Daten als die Antwort.

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

7
Vielen Dank für Ihre Antwort, aber ich verstehe Ihren Standpunkt mit der HTTP-Antwort nicht. Wir möchten das gesamte HTTP-Protokoll entfernen, um die Datenübertragung zu speichern. Und GETWrong Thing™
obendrein

Stimmen Sie architektonisch mit Ihnen überein, dass andere Verben wie POST (als universelles Verb) in REST-APIs mittlerweile häufiger vorkommen. Hängt davon ab, auf welchem ​​Reifegrad Sie Ihre REST-API entwickeln. Ich wollte nur zeigen, wie ein HTTP minimiert werden kann, während die Vorteile einer einfachen Implementierung und Kompatibilität mit vorhandenen Frameworks (Client und Server) erhalten bleiben und gleichzeitig die Lesbarkeit erhalten bleibt. Das Antworten mit einem Antwortbeispiel war verwirrend ... Wenn Sie die Daten senden möchten, würden Sie natürlich eine POST- oder GET-Nachricht verwenden - im Falle eines POST mit dem JSON-Inhalt, den ich in meinem ersten Beispiel gezeigt habe.
Christoph Bimminger

3

Es gibt kein "bestes" Protokoll. Nur eine Menge Kompromisse zu berücksichtigen:

  • Befinden sich Ihre Geräte in zufälligen Netzwerken mit blockierten zufälligen Ports? In diesem Fall ist es möglicherweise besser, HTTPS zu verwenden.

  • Wenn Sie UDP senden, können Sie jedes Mal die letzten N Messungen senden, sodass ein kleiner Paketverlust ignoriert wird. Sie können auch ACK-Pakete senden und UDP in ein zuverlässiges Protokoll verwandeln. (Die meisten Protokolle über UDP tun dies.)

  • Interessiert es Ihre Kunden, wenn ihre Daten unverschlüsselt verfügbar sind? Interessiert es Ihre Kunden, wenn Hacker schlechte Daten in diese unverschlüsselten Verbindungen einspeisen können? (Wenn ja, möchten Sie möglicherweise eine Verschlüsselung.)

  • Was passiert, wenn jemand an Ihrem Protokoll schnüffelt und die Daten manipuliert? Können Sie verhindern, dass ein Gerät Daten für ein anderes überschreibt?

  • Wie viele Geräte haben Sie maximal? Wie werden Sie mit all diesen Geräten umgehen? Wie werden Sie die Daten dorthin leiten, wo sie benötigt werden? Wie gehen Sie mit Wartung und Upgrades Ihrer Serverinfrastruktur um? Wenn Sie keine Erfahrung haben, überschätzen Sie wahrscheinlich Ihre Fähigkeit, viele gleichzeitige Verbindungen zu verarbeiten. Es kann am besten sein, an einen Anbieter auszulagern (und dessen Protokolle wie AWS IoT zu verwenden).


3

Wir haben einen genauen Test zum Vergleich der Übertragungsrate von HTTP und MQTT, siehe Test2 . In Ihrem aktuellen Szenario bringt MQTT 50-mal weniger Verkehr (und Batterie) als HTTP.

Grundsätzlich gibt es keinen Unterschied zwischen MQTT und einfachem TCP (in der Nachrichtengröße). Ich würde sogar sagen, dass es im Grunde keinen Unterschied zwischen einfacher TCP- und Binärnachricht und JSON in der MQTT-Nutzlast gibt. Auf diese Weise ist es viel bequemer, MQTT + JSON zu verwenden und sich bei der Datenlieferung und -darstellung auf diese Technologien zu verlassen. Nennen Sie einfach Ihre Schlüssel mehr oder weniger kurz.

In Bezug auf UDP ist es besser, TCP zu verwenden, wenn die Übertragung einmal pro Minute erfolgt. Wenn die Übertragung einmal pro 10 bis 20 Minuten oder länger erfolgt, können Sie UDP als eine verkehrs- / batterieeffektivere Lösung betrachten. Wenn Sie versuchen, ein eigenes Protokoll mit ACKs zu entwickeln, empfehle ich Ihnen, MQTT oder TCP zu verwenden und sich nur auf Ihren Geschäftsfall zu konzentrieren.

Im Allgemeinen - je einfacher Sie es implementieren, desto besser sind die Ergebnisse, die Sie in kürzester Zeit erzielen können. Wenn ich Sie wäre, würde ich in diesem Fall besser UDP + eigenes Binärformat und MQTT + JSON testen und eines davon auswählen. Oder starten Sie einfach von MQTT + JSON und überlegen Sie dann, ob es für meinen Fall in Ordnung ist.


1
Ich werde hier einige Worte gegen UDP erwähnen. Wir unterhalten ein großes SaaS-GPS-Flottenmanagementsystem (mehr als 1 Mio. Fahrzeuge verbunden) mit Kunden in mehr als 100 Ländern weltweit. Und kürzlich haben wir festgestellt, dass US-amerikanische Internetanbieter UDP-Pakete blockieren, die aus irgendeinem Grund aus den USA gesendet werden, selbst für M2M-Anwendungen. Es hat vor einigen Monaten begonnen, ist aber sehr schmerzhaft. Ich empfehle Ihnen daher, das TCP-basierte Protokoll (MQTT) auszuwählen und sich auf globale Standards zu verlassen. Eines Tages und in einigen Ländern werden Sie sogar gezwungen sein, MQTT über Websockets zu verwenden, um die Verbindung aufrechtzuerhalten. Nur ein kleiner Rat.
Shal
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.