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 логин, пароль и данные идут открытым текстом.
Источники
- 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: шаблоны # (любое число уровней, только в конце фильтра) и + (ровно один уровень)
- Espressif. ESP-IDF Programming Guide v6.1, ESP32: ESP-TLS — ESP-TLS по умолчанию работает поверх MbedTLS; сертификат CA для проверки сервера передают буфером cacert_buf или подключают пакет корневых сертификатов crt_bundle_attach
Нашли ошибку?
Смотрите также
- TCPНадёжный поток байтов поверх IP: рукопожатие, порты, подтверждения, keep-alive
- TLSШифрованный канал поверх TCP: рукопожатие, сертификаты, буферы и время на МК
- Беспроводные технологииWi-Fi, BLE, 802.15.4, nRF24, 433/868 МГц, LoRa: таблица параметров по даташитам
- Ethernet для микроконтроллераW5500, ENC28J60, MAC + PHY по RMII, LAN8720, DP83848, трансформатор и разводка
- OTA (обновление по воздуху)Обновление прошивки ESP32 из работающей программы по сети