Wybór odpowiedniego protokołu dla aplikacji IoT

12

W pracy mamy scenariusz IoT, w którym urządzenie Thing / Constrained wysyła swoją pozycję GPS w regularnych odstępach czasu do danego serwera. Ograniczone urządzenie to tablica podobna do Arduino, zasilana z baterii i wykorzystująca ekran GSM / SIM do łączności. Oto nasze cele projektowe:

  • Maksymalizacja żywotności baterii
  • Minimalizacja transferu danych

Do celów testowych wykorzystaliśmy protokół HTTP, w wyniku którego otrzymano wiadomości o wielkości około 500 bajtów, ale nadszedł czas, aby użyć bardziej odpowiedniego protokołu do transmisji danych. Niektóre cechy transferu danych to:

  • Ładowność jest dość małe, zwykle mniej niż 50 bajtów (dość daleko od typowego MTU, czyli wszystko powinno zmieścić się w pakiecie IP)
  • Dane należy przesyłać mniej więcej raz na minutę . Pewna wariancja nie jest krytyczna.
  • Można zgubić niektóre wiadomości
  • W tej chwili urządzenie nie potrzebuje żadnej odpowiedzi ze strony r (może się to jednak zmienić w przyszłości). Serwer nie musi też zaczynać żadnej rozmowy z urządzeniami.

Do tej pory myśleliśmy o tych możliwościach:

  • Niestandardowy protokół przez TCP . Pozbyłoby się to nagłówków HTTP, dzięki czemu komunikat byłby 10 razy mniejszy. To jest nasze niezawodne / konserwatywne podejście.
  • Niestandardowy protokół przez UDP . Ponieważ UDP ma mniejsze nagłówki i nie ma narzutów związanych z niezawodnością, oczekujemy, że będziemy dość wydajni. Jak skomentowano, utrata jednej wiadomości tutaj lub nie ma obaw ... mogą jednak występować inne problemy z niezawodnością, których nie jesteśmy świadomi.
  • MQTT (standard over TCP): Przy prawie żadnym istniejącym obciążeniu w porównaniu do TCP, może to być również opcja ... jednak nie mamy zbyt dużego doświadczenia z technologią GSM / SIM i nie wiemy, jak to zrobić ciągłe połączenie MQTT działałoby w ten sposób i czy wartość pasma pulsu połączenia jest warta takiego transferu danych o niskiej częstotliwości.
  • CoAP (standard w porównaniu z UDP): wydaje się również obiecujący. Tylko 4 bajty narzutów dla nagłówków i pracy przez UDP. Istnieją jednak nieznane zagrożenia związane z UDP.

Czy ktoś może dać jakąkolwiek wskazówkę? Z góry dziękuję.

bgusach
źródło
1
@RichardChambers w tym scenariuszu niezawodność nie jest tak ważna. Możemy sobie pozwolić na utratę niektórych pakietów tu czy tam. Acking nie jest konieczne. Myślę, że praca nad niezawodnością na UDP nie ma większego sensu, po to właśnie jest TCP.
bgusach,
1
Nie wymyśliłem koła na nowo, projektując własny protokół. Google CoAP vs. MQTT da ci więcej uwag. Czy potrzebujesz przyszłościowego rozwiązania, np. sprostać surowszym wymaganiom w przyszłości (gwarancje utraty, czas reakcji, interoperacyjność itp.)? Czy urządzenia mają NAT? Czy za bramami jest grupa urządzeń? Wiele niewiadomych ...
Wsparcie Gambit

Odpowiedzi:

6

Kilka przemyśleń na temat mojego doświadczenia z TCP, UDP i MQTT, a także dodatkowe zasoby do przejrzenia.

W przypadku UDP napotkałem problem cichej awarii, w której aplikacja w jednym węźle sieciowym, kliencie, widzi tylko niektóre wysłane wiadomości UDP. Jest zbyt wiele powodów, dla których ruch sieciowy może się nie udać. Problem z UDP polega na tym, że pakiety można odrzucać praktycznie za każdym razem, gdy którykolwiek z węzłów na ścieżce sieciowej między producentem pakietów a konsumentem pakietów jest uzasadniony. Zobacz temat Wikipedii Utrata pakietów .

Pytanie brzmi, jaki jest twój wskaźnik strat w dowolnym kontekście sieci. Jeśli więc jest to komunikacja w sieci LAN lub podsieci, wskaźnik strat może być niski. W sieci WAN lub w Internecie wskaźnik strat może być dość wysoki. Pakiety UDP są odrzucane z wielu powodów i kierowane, jednak warunki sieciowe na to pozwalają przy zmniejszeniu liczby przeskoków. Wysyłanie pakietów w wielką pustkę bez odpowiedzialności pozostawia otwartą możliwość cichych awarii.

Wygląda na to, że w twoim przypadku wystarczy zwykłe potwierdzenie z retransmisją po upływie czasu bez otrzymania potwierdzenia.

Zrobiłem wiadomości XML przez utrzymywane połączenie TCP i działało świetnie. Miałem warstwę, która dostarczała kompletne komunikaty w buforze do warstwy aplikacji do obsługi. Użyłem XML, aby spakować wiadomość znacznikiem początkowym XML na początku wiadomości i znacznikiem końcowym XML, aby wiedzieć, kiedy cała wiadomość została odebrana.

TCP ma kilka funkcji, takich jak sekwencyjna kolejność pakietów, brak powtórzeń, a bycie połączonym mechanizmem transportowym oznacza, że ​​wiesz, czy drugi koniec znika, czy nie, ale znalezienie go może trochę potrwać. Łączenie i rozłączanie może powodować opóźnienia, ale nie jest uciążliwe w zwykłych warunkach, chociaż warunki sieciowe mogą powodować spowolnienie przepustowości TCP.

MQTT jest protokołem transportowanym przez warstwę transportu sieciowego, zwykle TCP. MQTT korzysta z modelu publikowania / subskrybowania, więc nie ma przechowywania wiadomości. Kiedy więc wydawca opublikuje wiadomość, jeśli subskrybent nie jest połączony w tym czasie, to kiedy się połączy, nie zobaczy wiadomości. MQTT działa w czasie rzeczywistym, przypuszczam, że o to właśnie chodzi w części telemetrycznej akronimu. Lubię MQTT dla małych wiadomości i przeprowadzam eksperymenty z ładunkiem JSON poprzez MQTT przy użyciu Mosquitto. Zobacz ten artykuł Niezawodne dostarczanie wiadomości za pomocą Mosquitto (MQTT) z przeglądem MQTT i jakości usług. I zobacz ten krótki artykuł z linkami do zasobów, w tym przykładowej aplikacji IoT - MQTT Publish and Subscriber C Code .

Moje eksperymenty z MQTT przy użyciu tekstu JSON i bazy danych SQLite3 u subskrybenta do przechowywania wiadomości znajdują się pod adresem https://github.com/RichardChambers/raspberrypi/tree/master/mqtt, chociaż źródło znajduje się w C i jest dość nieuporządkowane.

Oto 13-minutowy film # 144 Protokoły internetowe: CoAP vs MQTT, Network Sniffing i przygotowania do hakowania IKEA Tradfri . To ciekawy artykuł o CoAP, ograniczonym protokole aplikacji: CoAP to „nowoczesny” protokół IoT . Oto podsumowanie CoAP:

Wcześni użytkownicy zgadzają się, że protokół ograniczonego stosowania działa wyjątkowo dobrze w przypadku ograniczonych sieci i urządzeń. Coś nie tak dobrze znanego: „W bardzo przepełnionej sieci bezprzewodowej - Wi-Fi lub komórkowej - CoAP może nadal działać, gdy protokół oparty na protokole transmisji (TCP), taki jak MQTT, nie może nawet ukończyć uzgadniania, - powiedział Vermillard.

Wynika to z faktu, że w przeciwieństwie do większości innych protokołów IoT, CoAP jest oparty na UDP. Innymi słowy, oznacza to brak uzgadniania protokołu lub korekcję błędów, jakie występują w przypadku protokołu TCP. „CoAP może nie być tak niezawodny jak HTTP lub gwarantować dostarczanie wiadomości takich jak MQTT, ale jest niezwykle szybki” - zauważył Matthieu. „Jeśli nie masz pewności, że niektóre wiadomości nie zostały odebrane, możesz wysłać o wiele więcej wiadomości w tym samym czasie”.

Jest jeszcze kilka innych, takich jak AMQP, STOMP i CBOR, na które możesz również spojrzeć. Zobacz standardową stronę internetową CBOR, a także tę tezę, Wdrażanie i ocena protokołu CBOR . Zobacz ten artykuł, Wybór protokołu przesyłania wiadomości: AMQP, MQTT lub STOMP, który porównuje i kontrastuje AMQP, MQTT i STOMP i kończy się notatką o brokerze RabitMQ:

Mamy nadzieję, że może to pomóc wielu osobom rozpocząć nawigację po protokole zupy dla każdego z przypadków użycia. Ponieważ firmy mają wiele aplikacji o różnych potrzebach, z pewnością możliwe jest, że będziesz potrzebować wszystkich trzech brokerów w różnych aplikacjach. W tym momencie pojawia się solidny wieloprotokolowy broker polyglot, taki jak RabbitMQ - ponieważ może wysyłać STOMP, MQTT lub AMQP i wydobywać jednego z pozostałych. Jeden z tych protokołów nie musi być zablokowany - wszystkie trzy są obsługiwane przez brokera RabbitMQ, co czyni go idealnym wyborem dla interoperacyjności między aplikacjami. Architektura wtyczek umożliwia również RabbitMQ ewolucję w celu obsługi dodatkowych lub zaktualizowanych wersji tych protokołów w przyszłości.

Ten pakiet udostępniania slajdów z około 60 slajdów porównuje i kontrastuje cztery różne protokoły IoT, uwzględniając potrzeby dwóch różnych grup IoT, Konsumentów i Przemysłu, które mają różne potrzeby w zakresie niezawodności i solidności. Jaki jest właściwy standard przesyłania wiadomości dla IoT? .

Richard Chambers
źródło
4

Brzmi jak idealna aplikacja dla UDP: topologia klient-serwer (pub / sub nie jest wymagana), tolerancja na utratę pakietów i duże przerwy między transmisjami pojedynczego pakietu oznaczają, że nadejście poza kolejnością nie stanowi problemu.

Oszczędności na nawiązywaniu połączeń i narzutach pakietów będą działać dobrze na twoją korzyść.

Trzeba tylko złagodzić problem cichej awarii. Jest na to wiele sposobów, ale sugeruję, aby serwer odpowiadał za każdym razem, gdy odbiera pakiety x (np. 10). W ten sposób klient wie, jak wiele jego pakietów przechodzi, a jeśli jest poniżej progu, może zwiększyć częstotliwość transmisji, aby przeciwdziałać utracie pakietów. Jeśli nic się nie przedostaje, TCP i tak nie pomoże, więc lepiej po prostu przestawić klienta w tryb zagrożenia, dopóki warunek nie zniknie.

Utrata pakietów UDP przez Internet na ogół nie jest wysoka, a jeśli jest to zwykle zjawisko przejściowe. GSM zapewnia buforowanie i ocenę sygnału radiowego, więc i tak zapewnia pewną tolerancję na fałszywy hałas.

Heath Raftery
źródło
4

Czy jesteś zewnętrznie ograniczony do korzystania z GSM / SIM?

Alternatywą może być użycie sieci LoRa, która:

  • są wysoce zoptymalizowane dla małych ładunków
  • są zaprojektowane z myślą o minimalnym zużyciu energii (a zatem maksymalnym czasie pracy baterii)
  • mają duży zasięg z założenia
  • mieć klasy połączeń (zawsze włączone, potwierdzone, niepotwierdzone)
  • mają zaplanowane okna pobierania (np. w celu aktualizacji oprogramowania lub ACK RX)

Możesz podłączyć się do istniejącej infrastruktury społecznościowej lub komercyjnej LoRa w większości krajów lub wdrożyć własne centra LoRa, jeśli byłoby to bardziej odpowiednie.

Aktywny rozwój na całym świecie i łatwa dostępność prototypowych osłon (na przykład dla Arduino).

BrendanMcL
źródło
1
Raz na minutę, jak wspomniano w pytaniu, jest zdecydowanie zbyt częste, aby zmieścić zalecane odstępy czasu transmisji węzła LoRa.
Chris Stratton
1
Zgadzam się, że 1 min jest zbyt często. Chociaż @bgusach nie wspomina o aplikacji. Jeśli ładunek może być kodowany binarnie w celu zmniejszenia rozmiaru i jeśli można zastosować interwał 3-5 minut (lub nawet 10 minut), może być idealny. W każdym razie, tylko sugestia, ponieważ zauważam, że nie była wcześniej wspomniana w odpowiedziach.
BrendanMcL
1
Tak, jeśli dobrze to czytam, coś w rodzaju 50 bajtów w czterominutowych odstępach może ledwo pasować; ale to wymaga weryfikacji, może być łatwo wyłączone co najmniej dwa razy.
Chris Stratton
1
Ciekawe, ale jesteśmy ograniczeni przez GSM / SIM (ma to być dobro konsumenckie, coś, co można kupić i wykorzystać gdziekolwiek bez infrastruktury poza siecią telefoniczną).
bgusach
3

Wolałbym minimalną odpowiedź HTTP z danymi JSON ... odpowiedź HTTP może być znacznie poniżej 500 bajtów transferu HTTP, a Ty pozostajesz kompatybilny z wieloma klientami dla aplikacji internetowych RESTful.

Minimalna wiadomość HTTP (np. Z wynikiem JSON) zawierająca około 130 bajtów danych HTTP wygląda następująco:

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

jeśli chcesz WYSŁAĆ dane z aplikacji na serwer, możesz po prostu użyć protokołu HTTP GET, w którym ustawiasz długość / długość jako parametry adresu URL. Żądanie zawiera jeszcze mniej danych niż odpowiedź.

GET /?lat=42.00000&long=10.0000 HTTP/1.1
Host: 192.168.0.2 
User-Agent: Proprietary
Accept: */* 
Connection: close
Christoph Bimminger
źródło
7
Dzięki za odpowiedź, ale nie rozumiem, o co ci chodzi z odpowiedzią HTTP. Chcemy pozbyć się całego protokołu HTTP, aby zaoszczędzić transfer danych. Co więcej, używanie GETdo modyfikowania zasobów jest Wrong Thing™do zrobienia
bgusach
Zgadzam się z tobą od strony architektonicznej, że inne czasowniki, takie jak POST (jako czasownik uniwersalny), są tymczasem bardziej powszechne w interfejsach API REST. Zależy od poziomu dojrzałości rozwijanego interfejsu API REST. Chciałem tylko pokazać, w jaki sposób można zminimalizować HTTP, jednocześnie zachowując łatwość implementacji i kompatybilność z istniejącymi platformami (klient i serwer), a jednocześnie zachowując czytelność dla człowieka. Odpowiedź z próbką odpowiedzi była myląca ... Jeśli chcesz WYSŁAĆ dane, oczywiście użyłbyś wiadomości POST lub GET - w przypadku POST, z treścią json, którą pokazałem w mojej pierwszej próbce.
Christoph Bimminger,
3

Nie ma „najlepszego” protokołu. Tylko wiele kompromisów do rozważenia:

  • Czy twoje urządzenia będą w losowych sieciach z zablokowanymi losowymi portami? Jeśli tak, lepiej użyć HTTPS.

  • Jeśli wysyłasz UDP, zawsze możesz wysłać za każdym razem ostatnie N pomiarów, tak aby utrata małych pakietów była ignorowana. Możesz również wysyłać pakiety ACK, zmieniając UDP w niezawodny protokół. (Większość protokołów oprócz UDP to robi.)

  • Czy Twoi klienci będą się przejmować, jeśli ich dane zostaną ujawnione w postaci niezaszyfrowanej? Czy Twoi klienci będą się przejmować tym, czy hakerzy mogą wprowadzać złe dane do niezaszyfrowanych połączeń? (Jeśli tak, możesz chcieć szyfrować.)

  • Co się stanie, jeśli ktoś wącha Twój protokół i manipuluje danymi? Czy możesz zapobiec zastępowaniu danych przez jedno urządzenie innym?

  • Ile masz urządzeń? Jak poradzisz sobie z tymi wszystkimi urządzeniami? Jak zamierzasz kierować dane do miejsca, w którym musi się udać? Jak radzisz sobie z utrzymaniem i aktualizacjami infrastruktury serwera? Jeśli nie masz doświadczenia, prawdopodobnie przeceniasz swoją zdolność do obsługi wielu jednoczesnych połączeń. Najlepszym rozwiązaniem może być outsourcing do dostawcy (i korzystanie z jego protokołów, takich jak AWS IoT).

BraveNewCurrency
źródło
3

Mamy dokładny test porównujący szybkość transmisji HTTP z MQTT, patrz test2 , w twoim obecnym scenariuszu MQTT przyniesie ci 50 razy mniej ruchu (i baterii) niż HTTP.

Zasadniczo nie ma różnicy między MQTT a zwykłym TCP (w rozmiarze wiadomości). Powiedziałbym nawet, że w zasadzie nie ma różnicy między zwykłym TCP a wiadomością binarną i JSON w ładunku MQTT. W ten sposób wygodniej jest korzystać z MQTT + JSON i polegać na tych technologiach w zakresie dostarczania i reprezentacji danych. Nazwij swoje klucze mniej więcej tak.

Jeśli chodzi o UDP, jeśli transmisja odbywa się raz na minutę, lepiej użyć protokołu TCP. Jeśli transmisja odbywa się raz na 10-20 minut lub więcej, możesz uznać UDP za rozwiązanie zwiększające natężenie ruchu / baterii. Jeśli spróbujesz opracować własny protokół za pomocą ACK, zalecam użycie MQTT lub TCP i skoncentrowanie się na uzasadnieniu biznesowym.

Ogólnie rzecz biorąc - im łatwiej go wdrożyć, tym najlepsze wyniki można osiągnąć w jak najkrótszym czasie. Na twoim miejscu lepiej przetestowałbym własny format binarny UDP + i MQTT + JSON i wybrałem jeden z nich. Lub nawet właśnie zacząłem od MQTT + JSON, a potem pomyśl, czy to jest OK w moim przypadku.

shal
źródło
1
Wspomnę tutaj kilka słów przeciwko UDP. Utrzymujemy duży system zarządzania flotą GPS SaaS (ponad 1 milion podłączonych pojazdów), mający klientów w ponad 100 krajach na całym świecie. Niedawno odkryliśmy, że dostawcy Internetu z USA blokują pakiety UDP wychodzące z USA z jakiegoś powodu, nawet w przypadku aplikacji M2M. Rozpoczęło się kilka miesięcy temu, ale jest bardzo bolesne, dlatego polecam wybrać protokół oparty na TCP (MQTT) i polegać na światowych standardach. Pewnego dnia, aw niektórych krajach będziesz nawet zmuszony do korzystania z MQTT przez gniazda sieciowe, aby utrzymać połączenie. Tylko mała rada.
shal