Понимание тем и подстановочных знаков MQTT в зависимости от случая
Что такое тема в MQTT?
Тема MQTT — это строка в кодировке UTF-8, которая является основой для маршрутизации сообщений в протоколе MQTT. Тема обычно выравнивается и отделяется косой чертой. /
между уровнями. Это похоже на пути URL, например:
chat/room/1
sensor/10/temperature
sensor/+/temperature
sensor/#
По сравнению с темами в других системах обмена сообщениями, например, Kafka и Pulsar, темы MQTT не нужно создавать заранее. Клиент создает тему при подписке или публикации, и удалять тему не нужно.
Хотя разрешено, обычно не рекомендуется использовать темы, начинающиеся или заканчивающиеся /
такой как /chat
или chat/
.
Ниже приведен простой процесс публикации и подписки MQTT. Если APP 1 подписывается на sensor/2/temperature
тема, он будет получать сообщения от Sensor 2, публикующие в эту тему.
Подстановочные знаки MQTT
Одноуровневый подстановочный знак
+
(U+002B) — это подстановочный знак, который соответствует только одному уровню темы. При использовании одноуровневого подстановочного знака одноуровневый подстановочный знак должен занимать весь уровень, например:
"+" is valid
"sensor/+" is valid
"sensor/+/temperature" is valid
"sensor+" is invalid (does not occupy an entire level)
Если клиент подписывается на тему sensor/+/temperature
он будет получать сообщения из следующих тем:
sensor/1/temperature
sensor/2/temperature
...
sensor/n/temperature
Но это не будет соответствовать следующим темам:
sensor/temperature
sensor/bedroom/1/temperature
Многоуровневый подстановочный знак
#
(U+0023) — это подстановочный знак, который соответствует любому количеству уровней в теме. При использовании многоуровневого подстановочного знака он должен занимать весь уровень и быть последним символом темы, например:
"#" is valid, matches all topics
"sensor/#" is valid
"sensor/bedroom#" is invalid (+ or # are only used as a wildcard level)
"sensor/#/temperature" is invalid (# must be the last level)
Темы, начинающиеся с $
Системные темы
Темы, начинающиеся с $SYS/
— это системные темы, которые в основном используются для получения метаданных о рабочем состоянии MQTT-брокера, статистике, клиентских онлайн-/офлайн-событиях и т. д. $SYS/
тема не определена в спецификации MQTT, однако большинство брокеров MQTT следуют этому рекомендация.
Например, EMQX поддерживает получение статуса кластера в следующих темах.
Тема | Описание |
---|---|
$SYS/brokers | Список узлов кластера EMQX |
$SYS/brokers/${node}/version | Версия брокера EMQX |
$SYS/brokers/${node}/uptime | Время запуска брокера EMQX |
$SYS/brokers/${node}/datetime | Время брокера EMQX |
$SYS/brokers/${node}/sysdescr | Описание брокера EMQX |
EMQX также поддерживает расширенные системные разделы, такие как клиентские онлайн/оффлайн события, статистика, системный мониторинг и аварийные сигналы. Для получения более подробной информации см. Темы системы EMQX документация.
Общие подписки — это функция MQTT 5.0, метода подписки, который обеспечивает балансировку нагрузки между несколькими подписчиками. Тема общей подписки начинается с $share.
Хотя протокол MQTT добавил общие подписки в версии 5.0, EMQX поддерживает общие подписки, начиная с MQTT 3.1.1.
На следующей диаграмме три подписчика подписываются на одну и ту же тему. $share/g/topic
с использованием метода общей подписки, где topic
это настоящее название темы, на которую они подписаны, а издатели публикуют сообщения в topic
но НЕТ к $share/g/topic
.
Кроме того, EMQX также поддерживает использование префикса общей подписки. $queue
в MQTT 3.1.1. Это частный случай общей подписки, который эквивалентен объединению всех подписчиков в одну группу.
Дополнительные сведения об общих подписках см. Общие подписки EMQX документация.
Темы в разных сценариях
Умный дом
Например, мы используем датчики для контроля температуры, влажности и качества воздуха в спальнях, гостиных и кухнях. Мы можем разработать следующие темы:
myhome/bedroom/temperature
myhome/bedroom/humidity
myhome/bedroom/airquality
myhome/livingroom/temperature
myhome/livingroom/humidity
myhome/livingroom/airquality
myhome/kitchen/temperature
myhome/kitchen/humidity
myhome/kitchen/airquality
Далее вы можете подписаться на myhome/bedroom/+
тема, чтобы получить данные о температуре, влажности и качестве воздуха для спальни, myhome/+/temperature
тема, чтобы получить данные о температуре для всех трех комнат, и myhome/#
тему, чтобы получить все данные.
Зарядка свай
ocpp/cp/cp001/notify/bootNotification
Опубликуйте онлайн-запрос в эту тему, когда зарядная свая будет в сети.
ocpp/cp/cp001/notify/startTransaction
Опубликуйте запрос на оплату в этой теме.
ocpp/cp/cp001/reply/bootNotification
Прежде чем зарядная свая выйдет в сеть, она должна подписаться на эту тему, чтобы получить онлайн-ответ.
ocpp/cp/cp001/reply/startTransaction
Перед тем, как зарядная свая инициирует запрос на оплату, она должна подписаться на эту тему, чтобы получить ответ на запрос на оплату.
Мгновенное сообщение
chat/user/${user_id}/inbox
Индивидуальный чат : пользователи подписываются на эту тему после того, как они в сети и будут получать сообщения от своих друзей. При ответе другу просто замените user_id темы на идентификатор друга.
chat/group/${group_id}/inbox
Групповой чат : после того, как пользователь успешно присоединится к группе, он может подписаться на тему, чтобы получать сообщения группы.
Добавить в друзья : опубликовать запрос на добавление в друзья в этой теме (user_id — это идентификатор друга).
Получать запросы на добавление в друзья : Подпишитесь на эту тему (user_id — это идентификатор подписчика), чтобы получать запросы на добавление в друзья от других пользователей.
Получать ответы на запросы в друзья : Перед добавлением в друзья пользователю необходимо подписаться на эту тему (user_id — id подписчика) для получения результатов запроса.
Ответить на запрос в друзья : отправить сообщение в эту тему (user_id — это идентификатор друга) о том, следует ли одобрить запрос на добавление в друзья.
Статус пользователь : Подпишитесь на эту тему, чтобы получать онлайн-статус своих друзей.
Часто задаваемые вопросы по темам MQTT
Каков максимальный уровень и длина темы MQTT?
Тема MQTT — это строки в кодировке UTF-8, и это НЕ ДОЛЖЕН быть больше 65535 байт. Однако на практике использование более коротких названий тем и меньшего количества уровней означает меньшее потребление ресурсов.
Старайтесь не использовать больше тематических уровней «только потому, что я могу». Например, my-home/room1/data
это лучший выбор, чем my/home/room1/data
.
Есть ли ограничение на количество тем?
Различные серверы сообщений имеют разные ограничения на количество тем. В настоящее время конфигурация EMQX по умолчанию не имеет ограничений на количество тем, но чем больше тем, тем больше памяти сервера будет использоваться.
Учитывая большое количество устройств, подключенных к MQTT Broker, мы рекомендуем клиенту подписываться не более чем на десять тем.
При маршрутизации сообщений в подписки с подстановочными знаками брокеру может потребоваться больше ресурсов, чем для тем без подстановочных знаков. Это разумный выбор, если можно избежать подписки с подстановочными знаками.
Это во многом зависит от того, как смоделирована схема данных для полезной нагрузки сообщения MQTT.
Например, если издатель публикует на device-id/stream1/foo
и device-id/stream1/bar
а подписчику нужно подписаться на оба, тогда он может подписаться device-id/stream1/#
. Лучшая альтернатива, возможно, состоит в том, чтобы поместить часть пространства имен foo и bar в полезную нагрузку, чтобы она публиковалась только в одной теме. device-id/stream1
а подписчик просто подписывается на эту одну тему.
Могу ли я подписаться на одну и ту же тему с помощью общей подписки и обычной подписки?
Да, но это не рекомендуется.
В соответствии со спецификацией MQTT несколько подписок приведут к доставке нескольких (дублированных) сообщений.
Каковы лучшие практики для тем MQTT?
- Не использовать
#
подписаться на все темы. - Тема не должна начинаться или заканчиваться
/
такой как/chat
илиchat/
. - Не используйте в теме пробелы и символы, отличные от ASCII.
- Использовать
_
или-
соединять слова (или верблюжий падеж) на уровне темы. - Старайтесь использовать меньше тематических уровней.
- Попробуйте смоделировать схему данных сообщения, чтобы избежать использования разделов с подстановочными знаками.
- Когда используется подстановочный знак, попробуйте переместить более уникальный уровень темы ближе к корню. например
device/00000001/command/#
это лучший выбор, чемdevice/command/00000001/#
.
Первоначально опубликовано на