Передача данных. MQTT. Знакомство с протоколом

 

 

 

Сегодня мы познакомимся с протоколом передачи данных MQTT.

MQTT — это протокол обмена сообщениями по шаблону издатель/подписчик (publisher/subscriber).

Аббревиатура наименования данного протокола расшифровывается как Message Queuing Telemetry Transport (MQTT). Если перевести дословно, то получится Транспорт телеметрии очереди сообщений.

MQTT — это облегчённый протокол с невысокой нагрузкой на каналы связи, работу в условиях постоянной потери связи и лёгкую встраиваемость в любую систему.

В наше время данный протокол активно используется в системах умного дома (IoT) для передачи данных от различных датчиков, для управления лампами, розетками и т.д.

Как правило MQTT работает по сети TCP/IP, но также может работать и  с другими моделями сетей и сетевыми протоколами, например, с ZigBee и Bluetooth.

Энди Стэнфорд-Кларк (IBM) и Арлен Ниппер (в то время работавший в Eurotech, Inc.) создали первую версию протокола в 1999 году. MQTT в то время использовался для мониторинга нефтепроводов в системе промышленного управления SCADA.

Несмотря на то, что MQTT изначально был закрытым, в 2010 году версия 3.1 вышла по лицензии royalty-free. В 2014 году MQTT стал официально утверждённым стандартом OASIS.

Протокол имеет небольшую транспортную часть (минимум 2 байта) и также небольшую часть формата посылки данных для снижения нагрузки на сеть.

Сейчас последней версией протокола является версия 5.0.

Только мы будем пользоваться версией 3.1.1, так как множество устройств, используемых в данное время, не поддерживают новую версию протокола 5.0.

Рассмотрим принцип обмена данными между устройствами по протоколу MQTT.

Система связи, построенная на MQTT, состоит из сервера-издателя, сервера-брокера и одного или нескольких клиентов. Издатель не требует каких-либо настроек по количеству или расположению подписчиков, получающих сообщения. Кроме того, подписчикам не требуется настройка на конкретного издателя. В системе может быть несколько брокеров, распространяющих сообщения. Клиент может быть как издателем сообщений, так и подписчиком на них

 

 

Брокер MQTT — это часть программного обеспечения, работающего на компьютере (локально или в облаке), и может быть создан самостоятельно или размещён третьей стороной. Он доступен как в реализациях с открытым исходным кодом, так и в проприетарных реализациях.

Брокер действует как почтовое отделение. Клиенты MQTT не используют адрес прямого подключения предполагаемого получателя, но используют строку темы, называемую тема или topic. Каждый, кто подписывается, получает копию всех сообщений по этой теме. Несколько клиентов могут подписаться на тему от одного брокера (возможность один ко многим), а один клиент может зарегистрировать подписки на темы у нескольких брокеров (многие к одному).

Идентификация публикуемых данных осуществляется при помощи уникальной строки типа

 

client1/device1/temp

client1/device1/hum

client1/device2/roz

 

Брокер использует такую строку для рассылки сообщений подписчикам.

Подписчики могут использовать специальные подстановочные знаки для подписки на сообщения определённого типа. Это нужно для того, чтобы клиент мог подписаться при помощи одного сообщения на все сообщения одного типа, а не подписываться на каждый топик в отдельном сообщении.

Например, используя вышеуказанные строки, клиент, подписавшись при помощи строки

 

client1/#

 

будет получать сообщения всех тем, находящихся в дереве client1.

Знак решётки # означает, что клиент подпишется на все темы начинающиеся со строки до этого знака, включая все вложенные подгруппы.

Чтобы не получать топики из вложенных подгрупп, вместо решетки используется занк плюс +.

То есть, если клиент подпишется со строкой

 

client1/+

 

то он ни один вид из вышеперечисленных топиков получать не будет, то есть не будет на них подписан, так как в них присутствуют вложенные группы device2 или device2. А вот если клиент-публикатор опубликует, например, топик

 

client1/counter1

 

то тогда наш клиент-подписчик сообщения из этого топика будет получать, то есть он на данную тему будет считаться подписанным.

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

Поэтому перейдём к краткому знакомству с форматом пакетов.

Формат полезных данных, передаваемых по протоколу MQTT, не стандартизирован, поэтому может быть закодирован в любом формате: XML, JSON и т.д.

Управляющие пакеты, как, впрочем, практически, все пакеты передачи данных других протоколов, имеют заголовок и полезную нагрузку.

Я не знаю, какие ещё бывают пакеты в MQTT кроме управляющих, так как во всей спецификации применяется к пакетам только это прилагательное, поэтому, с вашего позволения, в дальнейшем я буду применять формулировку просто пакеты.

Итак, пакеты данных MQTT включают в себя заголовок и полезную нагрузку

 

 

Заголовка может быть в некоторых пакетах и два — фиксированный и переменный.

То есть, во всех пакетах MQTT присутствует фиксированный заголовок, а переменный заголовок и полезная нагрузка могут быть не во всех пакетах.

Фиксированный заголовок имеет вот такой формат:

 

 

Первое поле MQTT Control Packet type — это самое главное поле заголовка, да и вообще, я считаю, что это главное поле пакета, несущее в себе тип пакета MQTT.

Всего существует 14 типов пакетов (в скобках направление).

 

1 — CONNECT: Запрос Клиента на подключение к серверу (клиент — сервер).

2 — CONNACK: Подтверждение подключения (сервер — клиент).

3PUBLISH: Публикация сообщения (оба направления).

4PUBACK: Подтверждение публикации (оба направления).

5PUBREC: Получение публикации (механизм гарантированной доставки часть 1) (оба направления).

6PUBREL: Сообщение для публикации отправлено (механизм гарантированной доставки часть 2) (оба направления).

7PUBCOMP: Публикация сообщения окончена (механизм гарантированной доставки часть 3) (оба направления).

8SUBSCRIBE: Запрос подписки от клиента (клиент — сервер).

9SUBACK: Подтверждение подписки (сервер — клиент).

10UNSUBSCRIBE: Запрос об отказе от подписки (клиент — сервер).

11UNSUBACK: Подтверждение отказа от подписки (сервер — клиент).

12PINGREQ: Запрос PING (клиент — сервер).

13PINGRESP: Ответ PING (сервер — клиент).

14DISCONNECT: Запрос отключения от клиента (клиент — сервер).

 

 

Второе поле Flags specific to each MQTT Control Packet type — это флаги

 

 

Флаги могут устанавливаться следующие.

 

Бит 3: Dup. Данный бит означает повторную доставку управляющего пакета PUBLISH.

Биты 1 и 2 несут в себе уровень качества услуги передачи пакета PUBLISH — QoS0, QoS1 и QoS2.

Бит 0RETAIN. Если данный бит установлен, то сообщение PUBLISH будет храниться в брокере, а новые подключенные клиенты будут получать данный пакет сразу же при подписке.

Третье поле Remaining Length — это количество байтов, оставшихся в текущем пакете, включая данные в переменном заголовке и полезную нагрузку. В это число не входят байты, используемые для кодирования самого числа оставшихся байтов, указанного в фиксированном заголовке.

Переменный заголовок присутствует не во всех пакетах MQTT  и находится он между фиксированным заголовком и полезной нагрузкой. Содержимое переменного заголовка зависит от типа управляющего пакета.

Поле Идентификатор пакета переменного заголовка является общим для нескольких типов пакетов

 

 

Поле идентификатора пакета состоит из 2 байтов — старшего и младшего. Содержат его управляющие пакеты PUBLISH (где QoS > 0), PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK.

Клиент и сервер назначают идентификаторы пакетов независимо друг от друга. В результате пары клиент-сервер могут участвовать в параллельных обменах сообщений с использованием одинаковых идентификаторов пакетов.

Пример. Клиент может отправить пакет PUBLISH с идентификатором пакета 0x1234, а затем получить другой пакет PUBLISH с идентификатором пакета 0x1234 со своего сервера, прежде чем он получит PUBACK по отправленному PUBLISH

 

 

Наше цель — только знакомство с протоколом, поэтому мы не будем сейчас подробно разбирать пакет каждого типа, тем более, что всё это есть в спецификации на официальном сайте здесь.

Давайте немного поговорим о флагах в фиксированном заголовке.

Флаг DUP ставится тогда, когда одна из сторон пытается повторно отправить пакет PUBLISH. Флаг DUP должен быть установлен на 0 для всех сообщений с уровнем качества обслуживания QoS0.

Теперь флаги уровня качества обслуживания QoS

 

 

Пакет PUBLISH не должен иметь оба бита QoS, установленные в 1. Если сервер или клиент получает пакет PUBLISH, у которого оба бита QoS установлены в 1, он должен прервать сетевое соединение.

Теперь кратко о каждом уровне качества безопасности.

QoS0: At most once delivery (Доставка не более одного раза).

Этот уровень используется для отправки сообщений с максимальной производительностью. При этом нет гарантии доставки. Используется при снятии показаний с датчиков, настроенных на непрерывную отправку данных.

QoS1: At least once delivery (Доставка не менее одного раза).

Данный уровень обеспечивает гарантированную доставку сообщений. При этом уровне возможно появление дубликатов сообщений. После получения дубликата сообщения брокер снова рассылает это сообщение подписчикам, а издателю снова посылает подтверждение получения сообщения.

QoS2: Exactly once delivery (Ровно одна доставка).

Данный уровень качества обслуживания является самым высоким уровнем качества обслуживания для использования в случаях, когда неприемлемы ни потери, ни дублирование сообщений. При передаче сообщений с данным уровнем качества обслуживания возрастают накладные расходы. Также данный уровень отличается сложностью его реализации.

Флаг RETAIN (флаг сохранения).

Если флаг RETAIN установлен в 1, в пакете PUBLISH, отправленном клиентом на сервер, сервер должен хранить сообщение приложения и значение его уровня качества обслуживания, чтобы оно могло быть доставлено будущим подписчикам, подписки которых соответствуют названию темы сообщения.

Немного о полезных данных, формат которых, как уже было указано выше, никак не регламентирован.

Полезная нагрузка содержит публикуемое сообщение приложения. Контент и формат данных специфичны для приложения. Длина полезной нагрузки может быть вычислена путем вычитания размера переменного заголовка из поля remaining length, которое находится в фиксированном заголовке. Это действительно в том числе и для пакета PUBLISH, содержащего полезную нагрузку нулевого размера.

Пример полезной нагрузки для пакета SUBSCRIBE

 

 

Подобная полезная нагрузка передаётся и в случае пакета UNSUBSCRIBE, только в данном случае уровень качества безопасности уже не передаётся

 

 

На этом, думаю, знакомство со столь знаменитым в данное время протоколом передачи данных MQTT мы закончим, так как тяжело, когда столько много теории. То, чего мы здесь не коснулись, а в дальнейшем вдруг потребуется, мы разберём в процессе использования протокола MQTT на практике в разработках ПО для наших схем.

Всем спасибо за внимание!

 

 

Передача данных Следующий урок

 

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

Data Transfer MQTT. Знакомство с протоколом

 

Смотреть ВИДЕОУРОК в Дзен (нажмите на картинку)

Data Transfer MQTT. Знакомство с протоколом

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*