Перейти к содержанию

MQTT

Датчик на ESP32 публикует температуру в топик, а телефон, сервер и реле подписаны на него и получают сообщение от брокера. Ни один из них не знает адресов остальных — в этом смысл MQTT.

Обновлено Редакция GAW

MQTT (Message Queuing Telemetry Transport) — протокол обмена сообщениями по схеме «издатель — подписчик» через посредника, брокер. Клиенты не обращаются друг к другу: один публикует сообщение в топик, брокер рассылает его всем, кто на этот топик подписан. MQTT работает поверх соединения TCP, поверх TLS или WebSocket; UDP без дополнительных средств, по стандарту OASIS, для него не подходит, потому что MQTT рассчитывает на упорядоченную доставку без потерь.

Топики и шаблоны

Топик — строка с уровнями через косую черту, например home/kitchen/temp. В фильтре подписки два шаблона: + заменяет ровно один уровень, # — любое число уровней и стоит только в конце. Подписка home/+/temp получит температуру всех комнат, home/# — всё, что лежит под home.

Качество доставки

QoSГарантия по OASISОбмен пакетамиЦена
0не более одного раза, возможна потеряPUBLISHминимальный трафик
1не менее одного раза, возможны дублиPUBLISH, PUBACKприёмник должен терпеть повтор
2ровно один разPUBLISH, PUBREC, PUBREL, PUBCOMPчетыре пакета, больше памяти на состояние

Уровень задаётся отдельно на каждом участке: от издателя до брокера и от брокера до подписчика. Подписчик получает сообщение с меньшим из двух значений — QoS публикации и максимального QoS, который брокер выдал его подписке (разд. 3.8.4). Повторную отправку неподтверждённых PUBLISH стандарт требует только при переподключении с сохранённой сессией (CleanSession = 0, разд. 4.4). Для периодических показаний датчиков обычно хватает QoS 0, для команд «включить реле» — QoS 1 с командами, которые безопасно выполнить дважды.

Что ещё есть в протоколе

  • Retain. Брокер хранит последнее сообщение топика с флагом RETAIN и сразу выдаёт его новому подписчику.
  • Last Will. Сообщение, которое брокер опубликует сам, если клиент пропал без пакета DISCONNECT, — удобный способ показать «устройство офлайн».
  • Keep Alive. Интервал в секундах, заданный клиентом при подключении. Если клиенту нечего отправлять, он шлёт PINGREQ; брокер разрывает соединение, если за полтора интервала от клиента ничего не пришло.

MQTT на микроконтроллере

Клиент MQTT держит одно соединение TCP с брокером, поэтому ему нужен стек TCP/IP: на ESP32 — встроенный, на микроконтроллере с W5500 — аппаратный (варианты описаны в статье «Ethernet для микроконтроллеров»). Сеть Wi-Fi и выбор радиомодуля разобраны в обзоре беспроводных интерфейсов. Порты по IANA — TCP 1883 без шифрования и 8883 с TLS. На порту 1883 имя, пароль и данные передаются открытым текстом, поэтому за пределами своей локальной сети подключайтесь к 8883 и проверяйте сертификат брокера. Тем же каналом часто передают команду на обновление прошивки по воздуху, а саму прошивку загружают по HTTPS.

Частые вопросы

Чем отличаются QoS 0, 1 и 2 в MQTT?

Это гарантии доставки между клиентом и брокером. QoS 0 — «не более одного раза»: сообщение отправлено без подтверждения и может потеряться. QoS 1 — «не менее одного раза»: отправитель хранит сообщение до подтверждения PUBACK и после переподключения с CleanSession = 0 обязан отправить его снова, поэтому возможны дубли. QoS 2 — «ровно один раз»: четыре пакета PUBLISH, PUBREC, PUBREL, PUBCOMP. Стандарт OASIS приводит для QoS 0 пример с показаниями датчика, где потеря одного отсчёта не важна.

Что такое retain и Last Will?

Сообщение с флагом RETAIN брокер запоминает и сразу отдаёт каждому новому подписчику топика — так подписчик узнаёт последнее состояние, не дожидаясь следующей публикации. Last Will (Will Message) клиент передаёт при подключении, а брокер публикует его сам, если соединение оборвалось без пакета DISCONNECT, например устройство потеряло питание.

Какой порт у MQTT?

По стандарту MQTT 3.1.1 в IANA зарегистрированы порты TCP 1883 для MQTT без шифрования и 8883 для MQTT поверх TLS. Через интернет используйте 8883 с проверкой сертификата брокера: на 1883 логин, пароль и данные идут открытым текстом.

Источники

  1. OASIS. MQTT Version 3.1.1, OASIS Standard, 29 October 2014 — разд. 1: публикация и подписка, три уровня качества доставки — «не более одного раза» (возможна потеря), «не менее одного раза» (возможны дубли), «ровно один раз»; разд. 1.5.3: строки UTF-8 длиной 0–65 535 байт; разд. 2.2.3: пакет до 268 435 455 байт (256 МБ); разд. 3.1.2.5–3.1.2.7: Will Message публикуется брокером при обрыве соединения без DISCONNECT, флаг Will Retain; разд. 3.1.2.10: Keep Alive — 16-битный интервал в секундах, без других пакетов клиент шлёт PINGREQ, брокер разрывает соединение, если за 1,5 интервала не получил ни одного пакета; разд. 3.3.1.3: RETAIN = 1 — брокер хранит сообщение и отдаёт его новым подписчикам; разд. 4.2: транспорт — TCP/IP, TLS или WebSocket, порты TCP 1883 и 8883 зарегистрированы в IANA для MQTT без TLS и с TLS, UDP сам по себе не подходит; разд. 3.8.4: QoS доставки подписчику — минимум из QoS публикации и выданного брокером максимума; разд. 4.3: QoS 0, 1, 2; разд. 4.4: повтор неподтверждённых PUBLISH и PUBREL обязателен только при переподключении с CleanSession = 0; разд. 4.7.1.2–4.7.1.3: шаблоны # (любое число уровней, только в конце фильтра) и + (ровно один уровень)
  2. Espressif. ESP-IDF Programming Guide v6.1, ESP32: ESP-TLS — ESP-TLS по умолчанию работает поверх MbedTLS; сертификат CA для проверки сервера передают буфером cacert_buf или подключают пакет корневых сертификатов crt_bundle_attach

Нашли ошибку?