Вечер буднего дня, PubSubClient только что установился, а малина с брокером осталась на даче — до выходных. Хотелось уже сейчас посмотреть, как плата публикует. Я вписал в setServer адрес test.mosquitto.org и порт 1883 — и подключение прошло за пару секунд: публичный тестовый сервер принимает кого угодно без регистрации. Скетч зашуршал температурой, я на радостях подписался на маску # — и в первую же минуту увидел чужие топики: чужие теплицы, чей-то котёл, чьи-то тестовые мигания диода.
А через два дня случилось то, что делает этот урок нужным: график дачной температуры показал 999. Такого значения мой скетч слать не умел. В журнале нашлась строка: сообщение в топик dacha/greenhouse/temp пришло от клиента, которого я не заводил. Имя топика я взял из самого ходового учебного примера — и какой-то другой ученик того же примера писал в ту же ветку. На публичном брокере топик принадлежит всем и никому: читать и писать в него может любой подключившийся.
Публичный брокер — отличная леса для первых шагов, и я до сих пор советую начинать именно с него. Но пользоваться общей площадкой надо по её правилам: здесь есть свои порты, свои ловушки с именами и своя этика нагрузки. Всё это — ниже, плюс план переезда на собственный брокер, который занимает один вечер.
Технически публичный брокер — обычный mosquitto (или кластер), у которого включён анонимный доступ. test.mosquitto.org — сервер проекта Mosquitto: аккаунт заводить не нужно, просто подключайся. Вторая такая площадка — broker.hivemq.com от HiveMQ: те же правила игры, тот же порт по умолчанию. Обе существуют ради тестов, и у обеих честная оговорка: гарантий нет. Сервер может лежать на профилактике, может терять сообщения, ничего не обещает ни по хранению, ни по времени отклика. Мой личный предел звучит так: публичный брокер — для проверки скетча и для экскурсий по чужому трафику, не для жизни.
Чем он удобен: ноль установки. Скачали библиотеку, вписали адрес — и у вас есть работающий брокер для первых опытов. Схему подключения мы разбирали в уроке про первый скетч с PubSubClient — там каркас соединения, который работает с любым адресом, хоть локальным, хоть публичным. Хосты меняются в одну строку, и это же свойство потом ускорит переезд к себе.
Масштаб у площадок разный, но порядок представления такой: на test.mosquitto.org одновременно живут тысячи клиентов. Отсюда и вторая ловушка — имена. Не только топики, но и clientId там общий: тысячу клиентов с именем esp32 библиотека отправит воевать между собой, и это будет бой на уничтожение — мы разбирали механику такой войны в уроке про clientId и статусы подключения.
Порты: куда стучаться с платы и из браузера
Порт 1883 — обычный MQTT без шифрования: для ESP32 с PubSubClient это самый короткий путь, работает из коробки. Порт 8883 — тот же протокол поверх TLS: PubSubClient умеет и так, но вместо WiFiClient ему нужен WiFiClientSecure с настроенным сертификатом — это отдельная история с тестовыми сертификатами, к ней стоит возвращаться, когда базовая связка уже полетала. Для отладки моей теплицы хватало 1883, а секреты я на публичную площадку и не выносил.
Порты 8080 и 8081 — MQTT поверх websockets, без шифрования и с TLS соответственно. С платы это нужно редко, а из браузера — всегда: браузерный javascript не умеет сырые TCP-сокеты, поэтому любой веб-дашборд ходит на брокер по websockets. Отсюда практический вывод, который сэкономит вам вечер: если плата шлёт, а браузерная панель молчит, первым делом сверяйте порт в адресе дашборда — там должен быть 8080 или 8081, а не 1883. У HiveMQ счёт свой: websockets живут на 8000, и это нормально — у каждой площадки карта портов своя. И ещё: websockets — не отдельный протокол, а тот же MQTT в конверте: те же топики, те же publish и subscribe, меняется только транспорт, поэтому скетч с платы и дашборд из браузера видят одну и ту же ветку.
| Порт | Что это | Кому нужен | Мой комментарий |
|---|---|---|---|
| 1883 | MQTT без шифрования | ESP32, PubSubClient, mosquitto_pub и sub | рабочий конёк для тестов; секретов в payload не держать |
| 8883 | MQTT поверх TLS | плата с WiFiClientSecure | шифрование есть, анонимность осталась: читать всё равно может любой |
| 8080 | websockets без TLS | браузерные дашборды на mqtt.js | браузер не умеет сырой TCP, поэтому для веба только websockets |
| 8081 | websockets поверх TLS | тот же браузер, канал шифруется | у HiveMQ свой счёт портов: websockets там на 8000 |
Своё имя: префикс топика и clientId
Правило уникального префикса родилось у меня из той истории с 999 градусами. Имя топика на публичном брокере — как адрес без города: что придумал, туда и пишут. Мой формат — ник, место, случайное число: ivan-dacha-742/greenhouse/temp. Число — то самое место, где встречаются два ученика одного учебника: с голым dacha/greenhouse/temp это случается регулярно. Свой префикс даёт и второй бонус — чистую ветку для подписки: подписан ivan-dacha-742/# — и чужой мусор не прилетает. Об устройстве топиков и масок мы говорили в первом уроке о протоколе, здесь работает та же грамматика.
clientId на общей площадке решает ту же задачу другим этажом. Имя esp32 на публичном брокере гарантированно занято: новое подключение с тем же паспортом рвёт старое, обе платы переподключаются по кругу, графики рвутся, а на беглый взгляд всё исправно. Мой приём — суффикс из случайного числа или из последних байтов MAC-адреса: ivan-esp32-742 уникален с вероятностью, которой хватает на годы.
Чужой писатель — это не только совпадение имён: публиковать можно в любую ветку, включая ваши командные. Поэтому железное правило, которое я вывесил над рабочим столом: команды исполнительным механизмам на публичном брокере не подаются вообще. Насос, реле 220 В, нагреватель — всё это живёт только за своим брокером, где имена топиков и право публикации под вашим контролем.
#include <PubSubClient.h> WiFiClient net;PubSubClient client(net); const char* BROKER = "test.mosquitto.org";const int PORT = 1883; // 8883 с TLS, 8080 websocketsString PREFIX = "ivan-dacha-742"; // ник-место-число: мой угол площадки void setup() { Serial.begin(9600); WiFi.begin("HomeNet", "12345678"); while (WiFi.status() != WL_CONNECTED) { delay(300); } client.setServer(BROKER, PORT); while (!client.connect("ivan-esp32-742")) { // суффикс вместо голого esp32 Serial.println("ne podklyuchilsya, povtor"); delay(3000); } client.subscribe("ivan-dacha-742/#"); // своя ветка, чужой мусор мимо Serial.println("gotov: publikuyu v svoyu vetku");} void loop() { client.loop(); unsigned long now = millis(); static unsigned long lastPub = 0; if (now - lastPub >= 5000) { // 5 секунд: достаточно для теплицы lastPub = now; int t = 18 + random(0, 9); client.publish((PREFIX + "/greenhouse/temp").c_str(), String(t).c_str()); }}Переезд к себе: план на один вечер
Публичный брокер — леса, а не дом. Как только скетч доказал, что умеет соединяться и публиковать, я переношу его на собственный брокер. Установка Mosquitto на малину или обычный ПК разобрана в уроке про установку брокера: apt install, две строки конфига, перезапуск сервиса. В скетче меняется одна строка — адрес в setServer. Топики, префикс и логика не трогаются вовсе: в этом и прелесть клиента, ему всё равно, чей брокер.
После переезда открываются этажи, которых у общей площадки нет: пароли через password_file, TLS с собственными сертификатами и главное — приватность, топики снова только ваши. Но есть и искушение, на которое я наступил: захотелось смотреть дачу из города, и рука потянулась пробросить порт 1883 на роутере. Не надо. Открытый наружу 1883 собирает сотни чужих попыток входа в час — первые пришли через пару минут после проброса, дальше сотни в час круглосуточно; я это увидел в логах и закрылся. Правильный ход — мост между домашним и облачным брокером, ему посвящён следующий урок: дом дотягивается до облака сам, ничего наружу не открывая.
Пока мост не настроен, посмотрите на площадку глазами журнала: симулятор ниже имитирует общий поток, который вы бы увидели в терминале с подпиской на # — ваши публикации рядом с чужими строками, с фильтром по префиксу и счётчиками.
- Поменяйте MOJ на свой вариант вида ник-число и запустите: все строки журнала перекрасятся в chuzhoy, потому что чужой префикс больше не совпадает с вашим. Это ровно то, что делает подписка на свою ветку вместо #.
- На настоящей плате поменяйте порт в setServer с 1883 на 8080 и попробуйте подключиться к test.mosquitto.org: соединение не сложится, PubSubClient рассчитывает на сырой MQTT, а там websockets. В журнале появится rc=-2 — тот же код, что и при недоступном адресе.
- Посчитайте поток: если на площадке 2000 клиентов и каждый публикует раз в 10 секунд, сколько сообщений в минуту проходит мимо подписки на #? Сверьтесь: 12000 в минуту, и это скромный сценарий.
- Составьте свой план переезда на один вечер: установка mosquitto, две строки конфига, замена адреса в setServer. Когда план написан, публичная площадка превращается из необходимости в прогулочную зону.
- Публичные брокеры — test.mosquitto.org и broker.hivemq.com — принимают анонимно и без гарантий: для тестов, не для жизни
- Порты: 1883 — MQTT, 8883 — MQTT поверх TLS, 8080 и 8081 — websockets для браузеров; у HiveMQ websockets на 8000
- Уникальный префикс топика (ник-место-число) и clientId с суффиксом спасают от соседей по площадке
- Всё опубликованное публично: никаких секретов в payload и никаких команд на реле 220 В с общей площадки
- Переезд на свой mosquitto — один вечер: в скетче меняется одна строка setServer, дальше — пароли и мосты
- 1. С каким периодом публикует этичный клиент на общей тестовой площадке?
- 2. График показал 999 градусов, хотя скетч слал честные 21-24. Что случилось?
- 3. Какой порт нужен браузерному дашборду на mqtt.js?
- 4. Две платы подключаются к test.mosquitto.org с одним clientId esp32. Что вы увидите?
- 5. Что из этого разумно публиковать на публичном брокере?
Частые вопросы по теме урока
- С каким периодом публикует этичный клиент на общей тестовой площадке?
- Публичный брокер — чужая машина на чужом счёту. Раз в 5-10 секунд для температуры достаточно, а поток в тысячу сообщений в секунду терпеть никто не обязан. Раз в 5-10 секунд для медленных величин вроде температуры
- График показал 999 градусов, хотя скетч слал честные 21-24. Что случилось?
- На публичном брокере имя топика ничьё: в ходовое dacha/greenhouse/temp пишет всякий, кто его взял. Лечение — уникальный префикс вида ник-место-число. В тот же топик писал другой ученик, взявший то же имя из примера
- Какой порт нужен браузерному дашборду на mqtt.js?
- Браузер не умеет сырые TCP-сокеты: веб-клиенты ходят по websockets. У test.mosquitto.org это 8080 без шифрования и 8081 с TLS. 8080 — MQTT поверх websockets
- Две платы подключаются к test.mosquitto.org с одним clientId esp32. Что вы увидите?
- clientId уникален в масштабе брокера, а на публичной площадке имя esp32 занято мгновенно. Суффикс в имени — суровая необходимость, не украшение. Обе вечно переподключаются: новое соединение рвёт старое
- Что из этого разумно публиковать на публичном брокере?
- Публично всё: читать и писать может любой. Наблюдаемые данные без секретов — да; команды исполнительным механизмам и любые секреты — только на своём брокере. Температуру теплицы в топик со своим префиксом