Вибір відповідного протоколу для програми IoT


12

На роботі у нас є сценарій IoT, в якому Thing / Constrained Device регулярно пересилає своє GPS-положення на даний сервер. Обмежений пристрій - це ардуїноподібна плата, яка працює від акумулятора і використовує GSM / SIM-щит для підключення. Це наші цілі дизайну:

  • Максимальне збільшення часу роботи акумулятора
  • Мінімізація передачі даних

Для тестування ми використовували HTTP, в результаті якого надходили повідомлення близько 500 байт, але саме час використовувати більш відповідний протокол для передачі даних. Деякі характеристики передачі даних:

  • Навантаження досить мала, зазвичай менше , ніж 50 байт (досить далекий від типового МТУЗІ, тобто все , що повинно поміститися в пакеті IP)
  • Дані слід надсилати приблизно раз на хвилину . Деяка дисперсія не є критичною.
  • Це нормально , щоб втратити деякі повідомлення
  • Зараз пристрою не потрібна відповідь від сервісу r (однак це може змінитися в майбутньому). Також сервер не повинен починати розмов з пристроями.

Поки ми думали про такі можливості:

  • Спеціальний протокол через TCP . Це дозволить позбутися заголовків HTTP, що роблять повідомлення в 10 разів менше. Це наш надійний / консервативний підхід.
  • Спеціальний протокол через UDP . Оскільки UDP має менші заголовки і не вимагає накладних витрат на надійність, ми очікуємо, що вони будуть досить ефективними. Як зазначається, втрата одного повідомлення тут або не викликає занепокоєння ... однак, можуть виникнути й інші проблеми з ненадійністю, про які ми не знаємо.
  • MQTT (стандартний для TCP): Оскільки майже немає існуючих накладних витрат у порівнянні з TCP, це також може бути варіантом ... однак, ми не маємо занадто багато досвіду роботи з технологією GSM / SIM, і не знаємо, як безперервне з'єднання MQTT працює таким чином, і чи варто пропускання частоти серцевих скорочень зв'язку для такої низькочастотної передачі даних.
  • CoAP (стандарт над UDP): Здається, також перспективним. Всього 4 байти накладок для заголовків і роботи над UDP. Однак невідомі ризики UDP існують.

Хто-небудь може дати якусь підказку? Заздалегідь спасибі.


1
@RichardChambers у цьому сценарії надійність не так важлива. Ми можемо дозволити собі втратити деякі пакунки тут чи там. Acking не є необхідним. Я думаю, що працювати над надійністю поверх UDP не має занадто великого сенсу, саме для цього і є TCP.
bgusach

1
Я б не винаходив колесо, створивши спеціальний протокол. Гугл CoAP проти MQTT надасть вам більше міркувань. Чи потрібно в майбутньому підтверджувати своє рішення, тобто. вирішувати більш жорсткі вимоги в майбутньому (гарантії втрат, час реагування, сумісність тощо)? Чи пристрої NAT'ed? Чи є групування пристроїв за шлюзами? Багато невідомих ...
Підтримка Gambit

Відповіді:


6

Кілька роздумів про мій досвід роботи з TCP, UDP та MQTT, а також деякі додаткові ресурси для перегляду.

За допомогою UDP я зіткнувся з проблемою тихої несправності, в якій додаток на одному мережевому вузлі, клієнт, бачить лише деякі повідомлення UDP, які були надіслані. Занадто багато причин, через які мережевий трафік може піти не так. Проблема з UDP полягає в тому, що пакети можуть бути відкинуті майже завжди, коли будь-який із вузлів мережевого шляху між виробником пакетів та споживачем пакетів вимагає. Дивіться тему Вікіпедії Втрата пакетів .

Питання полягає в тому, яка ваша втрата за будь-якого поточного контексту мережі. Отже, якщо це спілкування в межах локальної мережі або підмережі, ваш рівень втрат може бути низьким. У мережі WAN або через Інтернет ваш рівень втрат може бути досить високим. Пакети UDP з декількох причин відкидаються і маршрутизуються, проте мережеві умови дозволяють зменшити кількість переходів. Відправлення пакетів у велику порожнечу без відповідальності залишає відкритим можливість безшумних збоїв.

Це здається, що у вашому випадку достатньо просто просту дію з повторною передачею після тайм-ауту, не отримуючи жодного.

Я робив XML-повідомлення через підтримуване TCP-з'єднання, і це чудово працювало. У мене був шар, який доставляв повне повідомлення кожне в буфері до рівня програми для обробки. Я використовував XML для упаковки повідомлення із початковим тегом XML для початку повідомлення та тегом закінчення XML, щоб знати, коли було отримано все повідомлення.

TCP має кілька функцій, таких як послідовний порядок пакетів, відсутність повторів, а те, що є підключеним транспортним механізмом, означає, що ви знаєте, зникає чи ні інший кінець, хоча це може зайняти деякий час. Підключення та відключення може спричинити затримки, але не обтяжливі в звичайних умовах, хоча мережеві умови можуть призвести до сповільнення пропускної здатності TCP.

MQTT - це протокол, який транспортується мережевим транспортним рівнем, як правило, TCP. MQTT використовує модель публікації / підписки, щоб не зберігати повідомлення. Отже, коли видавець публікує повідомлення, якщо підписник не підключений у той момент, коли він дійсно підключається, він не побачить повідомлення. MQTT - це майже в реальному часі, я вважаю, що це те, що є частиною телеметрії в абревіатурі. Мені подобається MQTT для невеликих повідомлень і роблю кілька експериментів з корисним навантаженням JSON через MQTT за допомогою Mosquitto. Дивіться цю статтю Надійна доставка повідомлень за допомогою Mosquitto (MQTT) з оглядом MQTT та якості обслуговування. І дивіться цю коротку статтю із посиланнями на ресурси, включаючи зразок програми IoT - MQTT Publish і Subscriber C Code .

Мої експерименти з MQTT, використовуючи текст JSON та базу даних SQLite3 у підписника для зберігання повідомлень, знаходиться за адресою https://github.com/RichardChambers/raspberrypi/tree/master/mqtt, хоча джерело знаходиться в C і досить безладно.

Ось 13-хвилинне відео № 144 Інтернет-протоколів: CoAP проти MQTT, мережевий снайпер та підготовка до злому IKEA Tradfri . Це цікава стаття про CoAP, протокол обмеженого застосування: CoAP - це «сучасний» протокол IoT . Є такий підсумок CoAP:

Ранні користувачі погоджуються, що протокол обмеженої програми працює надзвичайно добре для обмежених мереж та пристроїв. Щось не так відоме: "У дуже перевантаженій бездротовій мережі - Wi-Fi або стільниковій - CoAP може продовжувати працювати там, коли протокол на основі протоколу управління передачею (TCP) на зразок MQTT навіть не може встигнути завершити рукостискання" - сказав Вермільярд.

Це тому, що на відміну від більшості інших протоколів IoT, CoAP побудований на UDP. Іншими словами, це означає відсутність рукостискань з протоколом або виправлення помилок, як це трапляється з TCP. "CoAP може бути не таким надійним, як HTTP або гарантувати доставку повідомлень, таких як MQTT, але це надзвичайно швидко", - зазначив Матьє. "Якщо у вас все в порядку, коли деякі повідомлення не надходять, ви можете надсилати ще багато повідомлень у той же часовий період."

Є кілька інших, таких як AMQP, STOMP і CBOR, на які ви також можете поглянути. Див. Веб-сайт стандарту CBOR , а також цю тезу, впровадження та оцінку протоколу CBOR . Дивіться цю статтю: Вибір протоколу обміну повідомленнями: AMQP, MQTT або STOMP, який порівнює та протиставляє AMQP, MQTT і STOMP і закінчується приміткою про брокера RabitMQ:

Сподіваємось, це може допомогти багатьом почати орієнтуватися на протокол супу для кожного із ваших випадків використання. Оскільки компаніям прийнято мати багато додатків з різними потребами, безумовно, можливо, вам можуть знадобитися всі три брокери в різних додатках. Ось тут і надійний мультипротокольний поліглот-брокер на зразок RabbitMQ, оскільки він може надсилати STOMP, MQTT або AMQP і виводити один з інших. Вам не потрібно бути заблокованим одним із цих протоколів - усі три підтримуються брокером RabbitMQ, що робить його ідеальним вибором для взаємодії між програмами. Архітектура плагінів також дозволяє RabbitMQ розвиватися для підтримки додаткових або оновлених версій цих протоколів у майбутньому.

Цей пакет слайдів із 60 слайдів дає порівняння та контраст між чотирма різними протоколами IoT, розглядаючи потреби двох різних IoT-груп, споживчих та промислових, які мають різні потреби в надійності та надійності. Що таке стандарт правильних повідомлень для IoT? .


4

Звучить як ідеальне додаток для UDP: топологія клієнт-сервер (pub / sub не потрібна), толерантна до втрати пакету та великі розриви між передачею одного пакету - це означає, що надходження поза замовлення не є проблемою.

Економія на налагодженні з'єднання та накладних пакетів буде добре працювати на вашу користь.

Вам просто потрібно пом'якшити проблему беззвучного відмови. Дуже багато способів зробити це, але моя пропозиція полягала б у тому, щоб сервер відповідав кожен раз, коли він отримує x (наприклад, 10) пакетів. Таким чином клієнт знає, скільки пакетів проходить через нього, і якщо він нижчий за поріг, він може збільшувати частоту передач, щоб протидіяти втратам пакету. Якщо нічого не проходить, TCP все одно не допоможе, тож вам краще просто перевести клієнта в режим лиха, поки стан не покращиться.

Втрати пакетів UDP в Інтернеті, як правило, не великі, і якщо це, звичайно, минущі явища. GSM забезпечує деяку буферизацію та оцінку радіосигналу, тому надає деяку толерантність до помилкового шуму.


4

Ви обмежені зовнішньою допомогою GSM / SIM?

Альтернативою може бути використання мережі LoRa, яка:

  • високо оптимізовані для невеликих корисних навантажень
  • розроблені для мінімального використання енергії (а отже, максимального часу роботи від акумулятора)
  • відрізняються великою дальністю дизайну
  • мати класи зв’язків (завжди увімкнено, визнано, не підтверджено)
  • мають заплановані вікна завантаження (наприклад, для оновлень прошивки або RX ACK)

Ви можете підключити до існуючої спільноти чи комерційної інфраструктури LoRa у більшості країн, або ви можете розгорнути власні хари LoRa, якщо це було б більш доречно.

У глобальному масштабі існує активна розробка та доступність екранування прототипів (наприклад, для Arduino).


1
Раз на хвилину, як згадується в питанні, занадто часто, щоб відповідати рекомендованим інтервалам передачі вузла LoRa.
Кріс Страттон

1
Погодьтеся 1 хвилина занадто часто. Хоча @bgusach не згадує програму. Якщо корисне навантаження може бути кодованим двійковим способом, щоб зменшити розмір, і якщо інтервал 3-5 хв (або навіть 10 хв) є придатним, то це може бути ідеальним. У будь-якому випадку, лише пропозиція, наскільки я зауважую, що вона раніше не згадувалася у відповідях.
BrendanMcL

1
Так, якщо я читаю це правильно, щось на кшталт 50 байт з інтервалом у чотири хвилини навряд чи підходить; але для цього потрібна перевірка, її можна легко вимкнути щонайменше в два рази.
Кріс Страттон

1
Цікаво, але ми обмежені GSM / SIM (це покликане бути споживчим товаром, що можна придбати та використовувати в будь-якому місці без будь-якої інфраструктури, крім телефонної мережі).
bgusach

3

Я вважаю за краще мінімальний відповідь HTTP з даними JSON ... відповідь HTTP може бути набагато нижче 500 байт передачі HTTP, і ви залишаєтеся сумісними з багатьма клієнтами для RESTful веб-додатків.

Мінімальне повідомлення HTTP (наприклад, з результатом JSON) з протоколом 130 байт даних HTTP виглядає так:

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

якщо ви просто хочете відправити дані з вашого додатка на сервер, ви можете просто використовувати HTTP GET, де ви встановили lat / long як параметри URL. У запиті є ще менше даних, ніж у відповіді.

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

7
Дякую за вашу відповідь, але я не бачу вашої точки зору у відповіді HTTP. Ми хочемо позбутися всього протоколу HTTP, щоб зберегти передачу даних. І на додаток до цього, GETдля зміни ресурсів є Wrong Thing™завдання
bgusach

Погодьтеся з архітектурною стороною, що інші дієслова на зразок POST (як універсальне дієслово) тим часом частіше зустрічаються в API REST. Залежить від того, на якому рівні зрілості ви розробляєте свій REST API. Просто хотілося показати, як HTTP можна звести до мінімуму, зберігаючи при цьому перевагу простого імпульсу та сумісності з існуючими рамками (клієнтом і сервером), і в той же час зберігати читабельність людини. Відповідь із зразком відповіді була заплутаною ... Якщо ви хочете надіслати дані, звичайно, ви використовуєте повідомлення POST або GET - у випадку POST, вміст json, який я показав у своєму першому зразку.
Крістоф Біммінгер

3

"Кращого" протоколу немає. Просто багато компромісів, які слід врахувати:

  • Чи будуть ваші пристрої у випадкових мережах із випадковими портами заблоковані? Якщо так, можливо, буде краще використовувати HTTPS.

  • Якщо ви надсилаєте UDP, ви можете кожного разу надсилати останні N вимірювань, щоб ігноруватися невеликі втрати пакетів. Ви також можете відправити пакети ACK, перетворивши UDP в надійний протокол. (Більшість протоколів поверх UDP роблять це.)

  • Чи будуть ваші клієнти піклуватися, якщо їх дані піддаються незашифрованим? Чи потурбуються ваші клієнти, якщо хакери можуть вводити погані дані в ті незашифровані з'єднання? (Якщо так, можливо, ви захочете шифрувати.)

  • Що станеться, якщо хтось нюхає ваш протокол і маніпулює даними? Чи можете ви запобігти одному пристрою перезаписувати дані на інший?

  • Скільки пристроїв у вас буде максимум? Як ви збираєтеся мати справу з усіма цими пристроями? Як ви збираєтеся направити дані туди, куди це потрібно відправити? Як ви маєте справу з технічним обслуговуванням та оновленням серверної інфраструктури? Якщо у вас немає досвіду, ви, мабуть, завищуєте свою здатність керувати багатьма одночасними з'єднаннями. Можливо, найкраще надати аутсорсинг постачальнику (і використовувати їхні протоколи, наприклад, AWS IoT).


3

У нас є точний тест порівняння швидкості передачі HTTP та MQTT, див. Test2 , у вашому поточному сценарії MQTT принесе вам у 50 разів менше трафіку (і акумулятора), ніж HTTP.

В основному немає різниці між MQTT та звичайним TCP (у розмірі повідомлення). Я б навіть сказав, що в основному немає різниці між простим TCP та бінарним повідомленням та JSON у корисному навантаженні MQTT. Таким чином, набагато зручніше використовувати MQTT + JSON і покладатися на ці технології для доставки та представлення даних. Просто назвіть свої ключі більш-менш короткими.

Щодо UDP, якщо передача відбувається раз на хвилину, тоді краще використовувати TCP. Якщо передача проводиться один раз на 10-20 хвилин або більше, ви можете розглянути UDP як більш ефективне рішення для руху трафіку та акумулятора. Якщо ви спробуєте розробити власний протокол з ACK, я рекомендую вам використовувати MQTT або TCP і просто зосередитись на вашому бізнесі.

Взагалі - чим простіше ви реалізуєте в ньому найкращі результати, яких можна досягти за найкоротший час. Якби я був ти, у такому випадку я б краще перевірити власний бінарний формат UDP + та MQTT + JSON і вибрати один із них. Або навіть просто почали з MQTT + JSON, а потім подумайте, чи нормально це для мого випадку.


1
Я згадаю тут кілька слів проти UDP. Ми підтримуємо велику систему управління автопарком SaaS GPS (підключено більше 1 млн транспортних засобів) з клієнтами в понад 100 країнах світу. І нещодавно ми виявили, що інтернет-провайдери, що базуються в США, блокують пакети UDP, які виходять із США, чомусь навіть для програм M2M. Він розпочався кілька місяців тому, але це дуже боляче, тому я рекомендую вибрати протокол на основі TCP (MQTT) і покладатися на глобальні стандарти. Колись і в деяких країнах вас навіть змусять використовувати MQTT через веб-розетки, щоб підтримувати зв’язок. Просто невелика порада.
ШЕЛ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.