ESP-MQTT это реализация клиента протокола MQTT, облегченного протокола обмена сообщениями по методу публикация/подписка (publish/subscribe). В настоящий момент ESP-MQTT поддерживает MQTT v5.0 [2].
Функции:
· Поддерживается MQTT поверх TCP, SSL с Mbed TLS, MQTT поверх WebSocket и MQTT поверх WebSocket Secure. · Простая настройка URI. · Несколько экземпляров (несколько клиентов в одном приложении). · Поддерживается subscribing, publishing, authentication, last will messages, keep alive pings и все 3 уровня Quality of Service (QoS). Это должно быть полнофункциональным клиентом.
Примеры приложений:
protocols/mqtt/tcp: MQTT поверх TCP, порт по умолчанию 1883. protocols/mqtt/ssl: MQTT поверх TLS, порт по умолчанию 8883. protocols/mqtt/ssl_ds: MQTT поверх TLS с использованием для аутентификации периферийного устройства цифровой подписи, порт по умолчанию 8883. protocols/mqtt/ssl_mutual_auth: MQTT поверх TLS с использованием сертификатов для аутентификации, порт по умолчанию 8883. protocols/mqtt/ssl_psk: MQTT поверх TLS с использованием для аутентификации предварительно распределенных ключей (pre-shared keys, PSK), порт по умолчанию 8883. protocols/mqtt/ws: MQTT поверх WebSocket, порт по умолчанию 80. protocols/mqtt/wss: MQTT поверх WebSocket Secure, порт по умолчанию 443. protocols/mqtt5: использует библиотеку ESP-MQTT для подключения к брокеру с MQTT v5.0.
[MQTT Message Retransmission]
Новое сообщение MQTT создается вызовом функции esp_mqtt_client_publish, или её не блокирующим аналогом esp_mqtt_client_enqueue.
Сообщения с QoS0 будут отправлены только 1 раз. У QoS1 и QoS2 другое поведение, поскольку протокол требует дополнительных шагов для завершения процесса.
Библиотека ESP-MQTT выбирает всегда повторно передавать не подтвержденные опубликованные сообщения QoS1 и QoS2, чтобы избежать их потерь на сбойных подключениях, несмотря на то, что спецификация MQTT [2] требует повторной передачи только при переподключении с флагом Clean Session, установленным в 0 (для такого поведения установите set disable_clean_session в true).
Сообщения QoS1 и QoS2, которые может понадобиться передать повторно, всегда помещаются в очередь, однако первая передача всегда пытается запуститься немедленно, если используется esp_mqtt_client_publish. Повторная передача не подтвержденных сообщений произойдет после таймаута message_retransmit_timeout. После CONFIG_MQTT_OUTBOX_EXPIRED_TIMEOUT_MS сообщения устаревают, и будут удалены. Если установлено CONFIG_MQTT_REPORT_DELETED_MESSAGES, то пользователю будет отправлено событие для оповещения.
[Конфигурация]
Конфигурация осуществляется установкой полей в структуре esp_mqtt_client_config_t. У этой структуры есть следующие подструктуры для конфигурации разных аспектов работы клиента.
broker_t позволяет установить адрес и проверку безопасности (security verification). credentials_t данные учетной записи клиента для аутентификации. session_t конфигурация для аспектов сессии MQTT. network_t конфигурация, связанная с сетью. task_t позволяет конфигурировать задачу FreeRTOS. buffer_t размер буфера для ввода и вывода.
В последующих секциях большинство общих аспектов рассматриваются подробнее.
[Брокер]
Адрес. Адрес брокера может быть установлен с помощью структуры address. Конфигурация может быть сделана заполнением поля uri, или комбинации hostname, transport и port. Опционально может быть установлен path, это поле полезно для соединений поверх WebSocket.
Поле uri используется по такой схеме формата scheme://hostname:port/path.
· В настоящее время поддерживаются схемы mqtt, mqtts, ws, wss.
· Примеры MQTT поверх TCP:
mqtt://mqtt.eclipseprojects.io: MQTT поверх TCP, порт по умолчанию 1883 mqtt://mqtt.eclipseprojects.io:1884: MQTT поверх TCP, порт 1884 mqtt://username:password@mqtt.eclipseprojects.io:1884: MQTT поверх TCP, порт 1884, с указанием имени username и пароля password
· Примеры MQTT поверх SSL:
mqtts://mqtt.eclipseprojects.io: MQTT поверх SSL, порт 8883 mqtts://mqtt.eclipseprojects.io:8884: MQTT поверх SSL, порт 8884
· Пример MQTT поверх WebSocket:
ws://mqtt.eclipseprojects.io:80/mqtt
· Пример MQTT поверх WebSocket Secure:
wss://mqtt.eclipseprojects.io:443/mqtt
Минимальная конфигурация:
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = "mqtt://mqtt.eclipseprojects.io",
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
esp_mqtt_client_start(client);
По умолчанию клиенты MQTT использует библиотеку с циклом обработки событий (event loop) для выдачи связанных с MQTT событий (connected, subscribed, published, и т. д.).
[Верификация]
Для безопасных соединений с использованием TLS и гарантии идентичности брокера должна быть установлена структура verification. Сертификат брокера может быть установлен в формате PEM или DER. Для выбора DER должно быть установлено поле certificate_len. Иначе должна в поле сертификата формата PEM быть предоставлена строка, завершенная нулем.
· Пример получения сертификата из сервера: mqtt.eclipseprojects.io
openssl s_client -showcerts -connect mqtt.eclipseprojects.io:8883 < /dev/null \
2> /dev/null | openssl x509 -outform PEM > mqtt_eclipse_org.pem
· Пример приложения: protocols/mqtt/ssl
· Конфигурация:
const esp_mqtt_client_config_t mqtt_cfg = {
.broker = {
.address.uri = "mqtts://mqtt.eclipseprojects.io:8883",
.verification.certificate = (const char *)mqtt_eclipse_org_pem_start,
},
};
Подробнее про заполнение других полей см. далее "Справочник по API" и "TLS Server verification" [3].
[Client Credentials]
Данные учетной записи клиента устанавливаются в поля подструктуры credentials.
username: указатель на строку имени пользователя для брокера, что может быть также установлено через URI. client_id: указатель на строку ID, по умолчанию устанавливается в ESP32_%CHIPID% где %CHIPID% это последние 3 байта от MAC-адреса в HEX (например "ESP32_b38F04").
Аутентификация. Можно установить параметры аутентификации через поле подструктуру authentication. Клиент поддерживает следующие методы аутентификации:
password: использовать установку пароля. certificate и key: взаимная аутентификация с TLS, обе стороны должны предоставить сертификат и ключ в формате PEM или DER. use_secure_element: использовать элемент безопасности, доступный в модуле ESP32-WROOM-32SE. ds_data: использовать периферийное устройство цифровой подписи (Digital Signature Peripheral), доступное в некоторых устройствах Espressif.
Сессия. Для конфигураций, связанных с сессией MQTT, должны быть установлены поля session.
Last Will and Testament. MQTT позволяет использовать сообщение Last Will and Testament (LWT, дословный перевод "завещание"), чтобы оповестить других клиентов о некорректном отключении клиента. Это конфигурируется следующими полями структуры last_will.
topic: указатель на тему LWT-сообщения. msg: указатель на LWT-сообщение. msg_len: длина LWT-сообщения, требуется если msg не указана null-terminated строкой. qos: Quality of Service для LWT-сообщения. retain: указывает флаг сохранения (retain) LWT-сообщения.
[Изменение настроек в меню конфигурации проекта]
Настройки для MQTT можно найти запуском idf.py menuconfig, в разделе Component config > ESP-MQTT Configuration. Доступны следующие настройки:
CONFIG_MQTT_PROTOCOL_311: разрешение версии 3.1.1 протокола MQTT. CONFIG_MQTT_TRANSPORT_SSL и CONFIG_MQTT_TRANSPORT_WEBSOCKET: разрешение определенного слоя транспорта MQTT, таких как SSL, WEBSOCKET и WEBSOCKET_SECURE. CONFIG_MQTT_CUSTOM_OUTBOX: запрет реализации по умолчанию mqtt_outbox, чтобы можно было предоставить специфичную реализацию.
[События]
Клиентом MQTT могут быть сгенерированы следующие события.
MQTT_EVENT_BEFORE_CONNECT: клиент инициализирован и начинает подключение к брокеру. MQTT_EVENT_CONNECTED: клиент успешно установил соединение с брокером. Теперь клиент готов к отправке и приему данных. MQTT_EVENT_DISCONNECTED: клиент оборвал соединение из за того, что не мог прочитать или записать данные, например из-за недоступности сервера. MQTT_EVENT_SUBSCRIBED: брокер подтвердил запрос клиента на подписку (subscribe request). Данные события будут содержать message ID сообщения подписки. MQTT_EVENT_UNSUBSCRIBED: брокер подтвердил запрос клиента на отписку (unsubscribe request). Данные события будут содержать message ID сообщения отписки. MQTT_EVENT_PUBLISHED: брокер подтвердил публикацию сообщения клиентом. Это сообщение будет выдано только для QoS1 и QoS2, поскольку QoS0 не использует подтверждения. Данные события будут содержать message ID опубликованного сообщения. MQTT_EVENT_DATA: клиент получил опубликованное сообщение. Данные события содержат: идентификатор сообщенгия (message ID), имя темы, на которую сообщение было опубликовано (name of the topic), принятые данные и их длина. Для данных, размер которых превышает размер внутреннего буфера, будет генерироваться несколько событий MQTT_EVENT_DATA, и current_data_offset и total_data_len из данных события будут обновляться, чтобы отслеживать фрагменты сообщения. MQTT_EVENT_ERROR: клиент столкнулся с ошибкой. Поле error_handle в данных события содержит значение error_type, которое может использоваться для идентификации ошибки. Тип ошибки будет определять, какие заполнены поля в структуре error_handle.
[Справочник по API]
Заголовочный файл: components/mqtt/esp-mqtt/include/mqtt_client.h.
В следующей таблице представлена сводное описание назначения функций ESP-MQTT API. Подробное описание функций, их параметров и используемых структур, типов, перечислений и макросов см. в документации [1].
Функция |
Описание |
esp_mqtt_client_init |
Создает дескриптор клиента MQTT на основе предоставленной в параметре конфигурации. |
esp_mqtt_client_set_uri |
Установит URI соединения MQTT. Эта функция обычно используется, чтобы переназначить URI, который был сконфигурирован esp_mqtt_client_init. |
esp_mqtt_client_start |
Запускает клиента MQTT с уже созданным дескриптором. |
esp_mqtt_client_reconnect |
Эта функция обычно используется для принудительного переподключения к определенному событию. |
esp_mqtt_client_disconnect |
Эта функция обычно используется для принудительного отключения от брокера. |
esp_mqtt_client_stop |
Останавливает задачи клиента MQTT. |
esp_mqtt_client_subscribe |
Подписывает клиента на определенную тему сообщений (topic) с определенным уровнем качества доставки (qos). |
esp_mqtt_client_unsubscribe |
Отписывает клиента от определенной темы сообщений. |
esp_mqtt_client_publish |
Функция для отправки публикации сообщения для брокера. |
esp_mqtt_client_enqueue |
Постановка сообщения в очередь outbox, для отправки позднее. Обычно используется для сообщений с qos > 0, но может также использоваться для сообщений qos = 0, если store = true. |
esp_mqtt_client_destroy |
Уничтожает дескриптор клиента MQTT. |
esp_mqtt_set_config |
Устанавливает структуру конфигурации, обычно используется при обновлении конфигурации (например на событиии "before_connect"). |
esp_mqtt_client_register_event |
Регистрирует событие MQTT. |
esp_mqtt_client_unregister_event |
Отменяет регистрацию события MQTT. |
esp_mqtt_client_get_outbox_size |
Получает размер outbox. |
esp_mqtt_dispatch_custom_event |
Отправка события пользователя во внутренний цикл обработки событий MQTT (mqtt internal event loop). |
[Ссылки]
1. ESP32-C3 ESP-MQTT site:docs.espressif.com. 2. Стандарт MQTT 5. 3. ESP32-C3 ESP-TLS site:docs.espressif.com. |