Выбор подходящего протокола для IoT-приложения


12

У нас в работе есть сценарий IoT, где устройство Thing / Constrained отправляет свое GPS-положение через определенный интервал времени на заданный сервер. Ограниченное устройство представляет собой Arduino-подобную плату с питанием от батареи и использует экран GSM / SIM для подключения. Это наши цели дизайна:

  • Максимальное время автономной работы
  • Минимизация передачи данных

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

  • Нагрузка довольно мала, обычно меньше , чем 50 байт (довольно далек от типичного МТУСА, то есть все , что должно поместиться в пакете IP)
  • Данные следует отправлять примерно раз в минуту . Некоторая разница не критична.
  • Можно потерять некоторые сообщения
  • Прямо сейчас, устройство не нуждается в каком-либо ответе от сервера (однако, это может измениться в будущем). Сервер также не должен начинать разговор с устройствами.

До сих пор мы думали об этих возможностях:

  • Пользовательский протокол по TCP . Это избавило бы от заголовков HTTP, делающих сообщение в 10 раз меньше. Это наш надежный / консервативный подход.
  • Пользовательский протокол по UDP . Поскольку UDP имеет меньшие заголовки и не влияет на надежность, мы ожидаем, что он будет довольно эффективным. Как прокомментировано, потеря одного сообщения здесь или здесь не является проблемой ... однако, могут быть другие проблемы с ненадежностью, о которых мы не знаем.
  • MQTT (стандарт по TCP): практически без существующей нагрузки по сравнению с TCP, это также может быть вариантом ... однако у нас нет большого опыта работы с технологией GSM / SIM, и мы не знаем, как это сделать Непрерывное MQTT-соединение будет работать таким образом, и стоит ли частота пульса соединения с такой низкочастотной передачей данных.
  • CoAP (стандарт по UDP): также кажется многообещающим. Только 4 байта для заголовков и работы по UDP. Однако существуют неизвестные риски UDP.

Кто-нибудь может дать намек? Заранее спасибо.


1
@RichardChambers в этом сценарии надежность не так важна. Мы можем позволить себе потерять некоторые пакеты здесь или там. AckВ этом нет необходимости. Я думаю, что работа над надежностью поверх UDP не имеет особого смысла, для этого и нужен TCP.
bgusach

1
Я бы не стал изобретать велосипед, разрабатывая собственный протокол. Google CoAP против MQTT даст вам больше соображений. Вам нужно будущее решение, т. Е. в будущем выполнять более строгие требования (гарантии потерь, время отклика, совместимость и т. д.)? Устройства NAT? Есть ли группировка устройств за шлюзами? Много неизвестных ...
Поддержка Гамбита

Ответы:


6

Несколько мыслей о моем опыте работы с TCP, UDP и MQTT, а также о некоторых дополнительных ресурсах для обзора.

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

Вопрос в том, какой у вас уровень потерь при любом текущем сетевом контексте. Так что, если это связь внутри локальной сети или подсети, уровень потерь может быть низким. В глобальной сети или в Интернете уровень потерь может быть довольно высоким. Пакеты 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 Hacking . Это интересная статья о 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: топология клиент-сервер (публикация / подпрограмма не требуется), устойчивость к потере пакетов и большие промежутки между передачами одного пакета означают, что поступление не по порядку не является проблемой.

Экономия на установлении соединения и пакетных издержках будет хорошо работать в вашу пользу.

Вам просто нужно смягчить проблему тихого сбоя. Есть много способов сделать это, но я бы предложил, чтобы сервер отвечал каждый раз, когда он получает 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) с HTTP-данными aprox 130 байтов выглядит следующим образом:

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

если вы просто хотите отправить данные из вашего приложения на сервер, вы можете просто использовать HTTP GET, где вы устанавливаете широту / долготу в качестве параметров 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.