У нас в работе есть сценарий 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.
Кто-нибудь может дать намек? Заранее спасибо.
Ack
В этом нет необходимости. Я думаю, что работа над надежностью поверх UDP не имеет особого смысла, для этого и нужен TCP.Ответы:
Несколько мыслей о моем опыте работы с 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:
Есть несколько других, таких как AMQP, STOMP и CBOR, которые вы также можете посмотреть. См. Стандартный веб-сайт CBOR, а также этот тезис « Внедрение и оценка протокола CBOR» . См. Эту статью Выбор протокола обмена сообщениями: AMQP, MQTT или STOMP, которая сравнивает и сравнивает AMQP, MQTT и STOMP и заканчивается примечанием о брокере RabitMQ:
Этот пакет слайдов, состоящий примерно из 60 слайдов, позволяет сравнивать и сравнивать четыре разных протокола IoT с учетом потребностей двух разных групп IoT: потребителей и промышленных компаний, которые имеют разные потребности в надежности и надежности. Какой правильный стандарт обмена сообщениями для IoT? ,
источник
Похоже на идеальное приложение для UDP: топология клиент-сервер (публикация / подпрограмма не требуется), устойчивость к потере пакетов и большие промежутки между передачами одного пакета означают, что поступление не по порядку не является проблемой.
Экономия на установлении соединения и пакетных издержках будет хорошо работать в вашу пользу.
Вам просто нужно смягчить проблему тихого сбоя. Есть много способов сделать это, но я бы предложил, чтобы сервер отвечал каждый раз, когда он получает x (например, 10) пакетов. Таким образом, клиент знает, сколько его пакетов проходит, и если он ниже порогового значения, он может увеличить частоту передач, чтобы компенсировать потерю пакетов. Если ничего не проходит, то TCP все равно не поможет, поэтому лучше просто перевести клиента в режим бедствия, пока состояние не исчезнет.
Потеря пакетов UDP через Интернет, как правило, невелика, и если это так, то это, как правило, временное явление. GSM обеспечивает некоторую буферизацию и оценку радиосигнала, поэтому в любом случае обеспечивает некоторую устойчивость к паразитным шумам.
источник
Внешне вы ограничены в использовании GSM / SIM?
Альтернативой может быть использование сети LoRa, которая:
Вы можете подключиться к существующей общественной или коммерческой инфраструктуре LoRa в большинстве стран или развернуть свои собственные центры LoRa, если это более уместно.
Существует активная разработка во всем мире и легкая доступность прототипов щитов (например, для Arduino).
источник
Я бы предпочел минимальный HTTP-ответ с данными JSON ... HTTP-ответ может быть намного ниже 500-байтовой передачи HTTP, и вы сохраняете совместимость со многими клиентами для веб-приложений RESTful.
Минимальное HTTP-сообщение (например, с результатом JSON) с HTTP-данными aprox 130 байтов выглядит следующим образом:
если вы просто хотите отправить данные из вашего приложения на сервер, вы можете просто использовать HTTP GET, где вы устанавливаете широту / долготу в качестве параметров URL. Запрос содержит даже меньше данных, чем ответ.
источник
GET
для изменения ресурсов являетсяWrong Thing™
сделатьНет «лучшего» протокола. Просто много компромиссов, чтобы рассмотреть:
Будут ли ваши устройства в случайных сетях с заблокированными случайными портами? Если это так, то может быть лучше использовать HTTPS.
Если вы отправляете UDP, вы всегда можете отправить последние N измерений каждый раз, так что небольшая потеря пакетов игнорируется. Вы также можете отправлять пакеты ACK, превращая UDP в надежный протокол. (Большинство протоколов поверх UDP делают это.)
Будут ли заботиться ваши клиенты, если их данные будут незашифрованными? Будут ли ваши клиенты заботиться о том, могут ли хакеры ввести плохие данные в эти незашифрованные соединения? (Если это так, вы можете захотеть шифрование.)
Что произойдет, если кто-то прослушивает ваш протокол и манипулирует данными? Можете ли вы запретить одному устройству перезаписывать данные для другого?
Сколько устройств у вас будет максимум? Как вы собираетесь бороться со всеми этими устройствами? Как вы собираетесь направить данные туда, куда они должны идти? Как вы справляетесь с обслуживанием и обновлением вашей серверной инфраструктуры? Если у вас нет опыта, вы, вероятно, переоцениваете свою способность обрабатывать много одновременных соединений. Может быть лучше передать стороннему поставщику (и использовать его протоколы, такие как AWS IoT).
источник
У нас есть точный тест, сравнивающий скорость передачи 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, а затем подумайте, нормально ли это для моего случая.
источник