Обзор функций MQTTv5.0. Часть 2
Приведенный ниже материал является продолжением статьи о функционале, добавленном в новой версии MQTTv5.0. Если вы уже успели ее изучить, то для вас не составит труда заметить, что большинство новых функций базируется на понятии свойств, которые можно добавлять в пакет. В этой статье мы подробно их разберем.
Прим. — Статья направлена на тех, кто имеет интерес или необходимость глубоко погружаться в тонкости MQTT. Здесь не будет картинок и лирических отступлений, только хардкор!!!
Далее приведена таблица всех свойств (см. п. 2.2.2.2 в спецификации).
Теперь давайте рассмотрим их поподробнее.
Payload Format Indicator — индикатор формата полезной нагрузки
- 0 — данные являются набором неопределенных байт, что эквивалентно отсутствию отправки индикатора формата полезной нагрузки,
- 1 — данные представляет собой кодированные символьные данные UTF-8.
Message Expiry Interval — интервал истечения сообщения
Число, представляющее интервал истечения срока действия сообщения (в секундах).
Если интервал истечения срока действия сообщения прошел и серверу не удалось доставить сообщение соответствующему абоненту, он должен удалить сообщение для этого абонента.
Content Type — тип содержимого
Значение типа содержимого определяется отправляющим и получающим клиентом.
Response Topic — топик для ответа
Строка UTF-8, которая используется в качестве топика для ответного сообщения.
Получатель сообщения с указанным топиком для ответа отправляет свой ответ, используя этот топик как топик своей публикации.
Взаимодействие запрос/ответ в этом случае происходит следующим образом (см. п. 4.10.1 в спецификации):
- Клиент (отправитель) публикует сообщение запроса с некоторым топиком, в котором указан топик для ответа.
- Другой клиент (получатель) предварительно подписывается на фильтр топиков, который соответствует имени топика, использовавшегося при публикации сообщения запроса. В результате он получает сообщение запроса. Может быть несколько клиентов, подписанных на этот топик или может не быть вовсе.
- Отвечающий клиент выполняет соответствующее действие на основе полученного сообщения, а затем публикует сообщение ответа с тем топиком, который был указан в свойстве с топиком ответа.
- При типичном использовании запрашивающая сторона предварительно подписывается на топик ответа и тем самым получает ответное сообщение. Однако какой-то другой клиент может быть подписан на топик ответа и в этом случае ответное сообщение также будет получено и обработано этим клиентом. Если при отправке ответного сообщения нет подписчиков на топик ответа, ответное сообщение не будет доставлено ни одному клиенту.
Correlation Data — корреляционные данные
Данные корреляции используются отправителем сообщения запроса, чтобы определить, к какому запросу относится сообщение ответа, когда оно получено. Если данные корреляции отсутствуют, то запрашивающая сторона не требует никаких данных корреляции.
Если сообщение запроса содержит корреляционные данные, получатель должен также включить эти корреляционные данные в качестве свойства в пакет PUBLISH ответного сообщения.
Значение данных корреляции имеет значение только для отправителя сообщения запроса и получателя сообщения ответа.
Subscription Identifier — идентификатор подписки
Число, представляющее идентификатор подписки.
Если публикация является результатом совпадения с более чем одной подпиской, будут указаны несколько идентификаторов подписки, в этом случае их порядок не имеет значения.
Клиент также может сделать несколько подписок, соответствующих данной публикации, и использовать один и тот же идентификатор для нескольких из них. В этом случае пакет PUBLISH будет содержать несколько идентичных идентификаторов подписки.
Идентификатор подписки связан с любой подпиской, созданной или измененной в результате пакета SUBSCRIBE. Если есть идентификатор подписки, он сохраняется вместе с подпиской. Если это свойство не указано, то отсутствие подписки сохраняется вместе с подпиской.
Идентификаторы подписки являются частью состояния сеанса на сервере и возвращаются клиенту, получающему соответствующий пакет PUBLISH. Они удаляются из состояния сеанса сервера, когда сервер получает пакет UNSUBSCRIBE, когда сервер получает пакет SUBSCRIBE от клиента для того же фильтра топиков, но с другим идентификатором подписки или без идентификатора подписки, или когда сервер отправляет Session Present равным 0 в пакете CONNACK.
Session Expiry Interval — интервал истечения сеанса
Число, представляющее интервал истечения сеанса (в секундах).
Если интервал истечения сеанса отсутствует, используется значение 0. Если он установлен в 0 или отсутствует, сеанс заканчивается, когда сетевое соединение закрыто.
Если интервал истечения сеанса равен 0xFFFFFFFF (UINT_MAX), сеанс не истекает.
Клиент и сервер должны хранить состояние сеанса после закрытия сетевого соединения, если интервал истечения сеанса больше 0.
Клиент может подключаться к серверу через сеть, которая обеспечивает прерывистое соединение. Этот клиент может использовать короткий интервал истечения сеанса, чтобы он мог повторно подключиться, когда сеть снова станет доступной, и продолжить надежную доставку сообщений. Если клиент не успеет восстановить соединение, сообщения будут потеряны.
Установка Clean Start равной 1 и интервалом истечения сеанса 0 эквивалентна установке CleanSession равной 1 в спецификации спецификации MQTT версии 3.1.1. Установка Clean Start в 0 и отсутствие интервала истечения сеанса эквивалентна установке CleanSession в 0 в версии спецификации MQTT 3.1.1.
Assigned Client Identifier — назначенный идентификатора клиента
Строка, которая является назначенным сервером идентификатором клиента. Используется, если в пакете CONNECT был использован идентификатор клиента нулевой длины.
Server Keep Alive — Keep Alive сервера
Число, определяющее время Keep Alive, назначенное сервером. Если сервер возвращает Server Keep Alive в пакете CONNACK, клиент должен использовать это значение вместо значения, отправленного им в качестве Keep Alive. Если сервер не отправляет Server Keep Alive, он должен использовать значение Keep Alive, установленное клиентом в пакете CONNECT.
Основное использование Server Keep Alive для сервера — проинформировать клиента о том, что он отключит клиента в случае неактивности раньше, чем наступит истечение времени Keep Alive, указанного клиентом.
Authentication Method — метод аутентификации
Строка, содержащая название метода аутентификации, используемого для расширенной аутентификации.
Если метод аутентификации отсутствует, расширенная аутентификация не выполняется.
Метод аутентификации — это соглашение между клиентом и сервером о значении данных, отправляемых в данных аутентификации и любых других полях в CONNECT, а также об обменах и обработке, необходимой клиенту и серверу для завершения аутентификации. Метод аутентификации обычно представляет собой механизм SASL.
Authentication Data — данные аутентификации
Двоичные данные, содержащие данные аутентификации. Отправляются только если указан метод аутентификации. Содержимое этих данных определяется методом аутентификации.
Request Problem Information — информация о проблеме запроса
Клиент использует это значение, чтобы указать, отправляется ли строка причины или пользовательские свойства в случае сбоев.
- 0 — сервер может вернуть строку причины или пользовательские свойства в пакете CONNACK или DISCONNECT, но не должен отправлять строку причины или пользовательские свойства в любом пакете, кроме PUBLISH, CONNACK или DISCONNECT,
- 1 — сервер может вернуть строку причины или пользовательские свойства для любого пакета, где это разрешено.
Will Delay Interval — интервал задержки Will Message
Число, представляющее интервал задержки Will Message (в секундах). Если интервал задержки отсутствует, значение по умолчанию равно 0 и перед публикацией Will Message задержки нет.
Сервер задерживает публикацию сообщения до тех пор, пока не истечет интервал задержки или не завершится сеанс, в зависимости от того, что произойдет раньше. Если новое сетевое соединение с этим сеансом установлено до того, как истечет интервал задержки, сервер не должен отправлять Will Message.
Одним из способов использования этого является предотвращение публикации Will Message, если существует временное отключение от сети и клиенту удается повторно подключиться и продолжить сеанс до публикации сообщения.
Request Response Information — запрос информации для ответа
Байт со значением 0 или 1. Клиент использует это значение, чтобы запросить у сервера информацию ответа в CONNACK.
- 0 — сервер не должен возвращать информацию ответа,
- 1 — сервер может вернуть информацию ответа в пакете CONNACK, но это не обязательно, даже если клиент запросил эту информацию.
Response Information — информация для ответа
Строка UTF-8, которая используется в качестве базы для создания Response Topic. Способ, которым клиент создает Response Topic из информации ответа, не определен этой спецификацией.
Обычно это используется для передачи уникальной в глобальном масштабе части топиков, которая зарезервирована для этого клиента, по крайней мере, на время жизни его сеанса. Использование этого механизма позволяет выполнить эту настройку один раз на сервере, а не на каждом клиенте.
Server Reference — ссылка на сервер
Строка, которая может использоваться клиентом для идентификации другого используемого сервера. Значение этой строки представляет собой список ссылок, разделенных пробелами. Формат ссылок не регламентирован.
Сервер может запросить, чтобы клиент использовал другой сервер, отправив CONNACK или DISCONNECT с кодом причины “Использовать другой сервер” или “Сервер перемещен”. При отправке одного из этих кодов, сервер может также включать свойство ссылки на сервер, чтобы указать местоположение сервера или серверов, которые клиент должен использовать.
- Использовать другой сервер — клиент должен временно переключиться на использование другого сервера.
- Сервер перемещен — клиент должен всегда подключаться к другому серверу.
Рекомендуется, чтобы каждая ссылка состояла из имени, за которым следуют двоеточие и номер порта. Если имя содержит двоеточие, строка имени может быть заключена в квадратные скобки. Имя, заключенное в квадратные скобки, не может содержать символ правой квадратной скобки («]»). Это используется для представления адреса IPv6, который использует в качестве разделителя двоеточия.
Имя в ссылке на сервер обычно представляет собой имя хоста, DNS-имя, SRV-имя или IP-адрес. Значение после двоеточия обычно представляет собой номер порта в десятичном виде. Это не требуется, если информация о порте берется из имени (например, для SRV) или используется по умолчанию.
Если дано несколько ссылок, ожидается, что клиент выберет одну из них.
Примеры:
myserver.xyz.org myserver.xyz.org:8883 10.10.151.22:8883 [fe80::9610:3eff:fe1c]:1883
Reason String — строка причины
Строка, описывающая причину, связанную с этим ответом. Сервер использует это значение для предоставления дополнительной информации клиенту.
Правильное использование строки причины в клиенте будет включать использование этой информации в исключении, генерируемом кодом клиента, или запись этой строки в журнал.
Receive Maximum — максимальное значение количества пакетов QOS>0
Число, устанавливающее квоту отправки, которая используется для ограничения количества пакетов PUBLISH QOS> 0, которые могут быть отправлены без получения PUBACK (для QoS 1) или PUBCOMP (для QoS 2). То есть это значение используется для ограничения количества публикаций QoS 1 и QoS 2, отправляемых одновременно. Клиент/сервер не должны отправлять сообщения с QoS 1 и QoS 2, если есть отправленные сообщения количества Receive Maximum, на которые еще не получены ответы. При достижении Receive Maximum отправку пакетов с QoS 0 также можно приостановить, но не обязательно. При этом задерживать отправку пакетов, отличных от PUBLISH, не требуется.
Если и клиент, и сервер установили Receive Maximum равным 1, они удостоверяются, что не будет более одного сообщения «в полете» одновременно.
Указанное значение применяется только к текущему сетевому соединению и инициализируется повторно при переподключении.
Если значение не указано, то по умолчанию оно равно 65 535.
Topic Alias Maximum — максимальное значение псевдонима топика
Число, представляющее максимальное значение псевдонима топика.
Это значение указывает самое большое значение, которое принимается в качестве псевдонима топика. Оно используется, чтобы ограничить количество псевдонимов топиков, которые необходимо хранить в этом соединении.
Topic Alias — псевдоним топика
Чтобы уменьшить размер пакета PUBLISH, отправитель может использовать псевдоним топика. Это целочисленное значение, которое используется для идентификации топика вместо использования имени топика. Такой способ уменьшает размер пакета PUBLISH и полезен, когда имена топиков длинные и одни и те же имена часто используются повторно в сетевом соединении.
На стороне получателя при получении псевдонима для топика устанавливается необходимое соответствие между топиком и его псевдонимом.
Если пакет PUBLISH содержит псевдоним топика, получатель обрабатывает его следующим образом (см. п. 3.3.4 в спецификации):
1.Если получатель уже установил сопоставление для псевдонима топика, то a) Если пакет имеет топик нулевой длины, получатель обрабатывает его, используя имя топика, которое соответствует псевдониму топика b) Если пакет содержит топик ненулевой длины, получатель обрабатывает пакет, используя это имя топика, и обновляет свое отображение для псевдонима топика на имя топика из входящего пакета. 2.Если у получателя еще нет сопоставления для этого псевдонима, то a) Если пакет имеет топик нулевой длины, это ошибка протокола b) Если пакет содержит топик с ненулевой длиной, получатель обрабатывает пакет с использованием этого имени топика и устанавливает его сопоставления для псевдонима топика с именем топика из входящего пакета.
Maximum QoS — максимальный QoS
Принимает значение 0 или 1. Если максимальное QoS отсутствует, клиент использует максимальное QoS — 2.
Если сервер не поддерживает пакеты PUBLISH QoS 1 или QoS 2, он должен отправить максимальное QoS в пакете CONNACK, указав самое высокое QoS, которое он поддерживает.
Если Клиент получает максимальное QoS от Сервера, он не должен отправлять пакеты PUBLISH с уровнем QoS, превышающим указанный максимум.
Retain Available — доступно сохранение
- 0 — сохраненные сообщения не поддерживаются,
- 1 — сохраненные сообщения поддерживаются.
Клиент, получающий значение Retain Available с сервера равное 0, не должен отправлять пакет PUBLISH с флагом RETAIN, установленным на 1.
User Property — cвойство пользователя
Представляет собой строковую пару “имя”-“значение”. Это свойство, в отличие от других, может появляться несколько раз. Одно и то же имя может использоваться для нескольких свойств.
Это свойство может использоваться для предоставления дополнительной диагностической или другой информации.
Значение этих свойств не определено в спецификации, их значение и интерпретация известны только отправляющим и получающим клиентам.
Maximum Packet Size — максимальный размер пакета
Число, определяющее максимальный размер пакета, который клиент/сервер готов принять. Размер пакета — это общее количество байтов в пакете MQTT. Это свойство используется, чтобы сообщить о том, что пакеты, превышающие это ограничение, не будут обрабатываться.
Если максимальный размер пакета отсутствует, ограничение размера пакета не накладывается.
Приложение несет ответственность за выбор подходящего значения максимального размера пакета, если оно решает ограничить размер пакета.
Wildcard Subscription Available — доступна подписка с подстановочными знаками
- 0 — подписки с подстановочными знаками не поддерживаются,
- 1 — такие подписки поддерживаются.
Если свойство отсутствует, то подписки с подстановочными знаками поддерживаются.
Если сервер поддерживает подписки с подстановочными знаками, он все равно может отклонить определенный запрос на подписку, содержащий подписку с подстановочными знаками.
Subscription Identifier Available — доступен идентификатор подписки
- 0 — идентификаторы подписки не поддерживаются,
- 1 — идентификаторы подписки поддерживаются.
Если свойство отсутствует, то идентификаторы подписки поддерживаются.
Shared Subscription Available — доступна общая подписка
- 0 — общие подписки не поддерживаются,
- 1 — общие подписки поддерживаются.
Если свойство отсутствует, то общие подписки поддерживаются.
Заключение
Напомню, что статья родилась при работе над встраиванием появившейся функциональности, описанной выше, в сервис платформы Интернета вещей. Также мне показалось, что довольно удобно вывести отображение полученных от клиента свойств в интерфейс объекта. Можно скрывать неинтересные свойства, можно добавлять отображение дополнительных пользовательских свойств. В общем виде это выглядит так.
Вот, пожалуй, и всё. Для тестирования функциональности мне показался довольно удобным и наглядным вот этот проект redboltz/mqtt_cpp.
Буду очень рада, если в комментариях вы поделитесь другими open-source проектами MQTT-клиентов (как с GUI, так и без него), поддерживающих версию 5.0.
Больше полезных материалов читайте в моем блоге на хабре.