Настройка MQTT брокера mosquitto

Binar

New member
Всем здравия.
На винде запущен брокер Москито. Все сообщения идут с флагом ретайн. Но после перезагрузки брокера (запуск / останов службы) данные не сохраняются. Это нормальное поведение брокера?
Что нужно сделать для того что бы после перезапуска, последние данные восстанавливались?
 

Binar

New member
Дополню пост содержанием файла
mosquitto.conf

Код:
allow_anonymous false
password_file %ProgramFiles%\mosquitto\passwd
persistence true
persistence_location %ProgramFiles%\mosquitto\
autosave_interval
check_retain_source false
log_dest topic
log_type error
log_type warning
log_type notice
log_type information
connection_messages true
log_timestamp true
 

Binar

New member
Вопрос снят.
рабочий файл:
Код:
allow_anonymous false
password_file %ProgramFiles%\mosquitto\passwd
persistence true
persistence_file mosquitto.db
autosave_interval 5
check_retain_source false
log_dest topic
log_type error
log_type warning
log_type notice
log_type information
connection_messages true
log_timestamp true
 

Casper

Member
Столкнулся с такой проблемой. Установил mosquitto брокер на Windows, запустил как службу, для проверки работы использую mqtt spy. В ESP32 использую библиотеку async MQTT client и следующий код для теста
Код:
/*
This example uses FreeRTOS softwaretimers as there is no built-in Ticker library
*/
#include <Arduino.h>

#include <WiFi.h>
extern "C" {
    #include "freertos/FreeRTOS.h"
    #include "freertos/timers.h"
}
#include <AsyncMqttClient.h>

#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"

#define MQTT_HOST IPAddress(192, 168, 3, 137)
#define MQTT_PORT 1883

AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;

unsigned long oldTime;
unsigned long interval = 5000;

void connectToWifi() {
  Serial.println("Connecting to Wi-Fi...");
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}

void connectToMqtt() {
  Serial.println("Connecting to MQTT...");
  mqttClient.connect();
}

void WiFiEvent(WiFiEvent_t event) {
    Serial.printf("[WiFi-event] event: %d\n", event);
    switch(event) {
    case SYSTEM_EVENT_STA_GOT_IP:
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
        connectToMqtt();
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        Serial.println("WiFi lost connection");
        xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
            xTimerStart(wifiReconnectTimer, 0);
        break;
    }
}

void onMqttConnect(bool sessionPresent) {
  Serial.println("Connected to MQTT.");
  Serial.print("Session present: ");
  Serial.println(sessionPresent);
  // uint16_t packetIdSub = mqttClient.subscribe("test/lol", 2);
  // Serial.print("Subscribing at QoS 2, packetId: ");
  // Serial.println(packetIdSub);
  // mqttClient.publish("test/lol", 0, true, "test 1");
  // Serial.println("Publishing at QoS 0");
  // uint16_t packetIdPub1 = mqttClient.publish("test/lol", 1, true, "test 2");
  // Serial.print("Publishing at QoS 1, packetId: ");
  // Serial.println(packetIdPub1);
  // uint16_t packetIdPub2 = mqttClient.publish("test/lol", 2, true, "test 3");
  // Serial.print("Publishing at QoS 2, packetId: ");
  // Serial.println(packetIdPub2);
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  Serial.println("Disconnected from MQTT.");

  if (WiFi.isConnected()) {
    xTimerStart(mqttReconnectTimer, 0);
  }
}

void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
  Serial.println("Subscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
  Serial.print("  qos: ");
  Serial.println(qos);
}

void onMqttUnsubscribe(uint16_t packetId) {
  Serial.println("Unsubscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
  Serial.println("Publish received.");
  Serial.print("  topic: ");
  Serial.println(topic);
  Serial.print("  qos: ");
  Serial.println(properties.qos);
  Serial.print("  dup: ");
  Serial.println(properties.dup);
  Serial.print("  retain: ");
  Serial.println(properties.retain);
  Serial.print("  len: ");
  Serial.println(len);
  Serial.print("  index: ");
  Serial.println(index);
  Serial.print("  total: ");
  Serial.println(total);
  Serial.println(((String)payload).substring(0,len));
}

void onMqttPublish(uint16_t packetId) {
  Serial.println("Publish acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();

  mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
  wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));

  WiFi.onEvent(WiFiEvent);

  mqttClient.onConnect(onMqttConnect);
  mqttClient.onDisconnect(onMqttDisconnect);
  mqttClient.onSubscribe(onMqttSubscribe);
  mqttClient.onUnsubscribe(onMqttUnsubscribe);
  mqttClient.onMessage(onMqttMessage);
  mqttClient.onPublish(onMqttPublish);
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);

  connectToWifi();
}

void loop() {

  if(millis() - oldTime > interval){
    Serial.println("Send message on MQTT");
    oldTime = millis();

    mqttClient.publish("banya/id1/data/ip", 2, false, WiFi.localIP().toString().c_str());
    mqttClient.publish("banya/id1/data/freeHeap", 2, false, String(ESP.getFreeHeap()).c_str());
  }
}
и в консоли у меня вот такая ерунда происходит, отправляется пару сообщений и идет переподключение к брокеру, иногда одно сообщение отправляет и сразу переподключается и второе сообщение уже не отправляет.
Код:
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Publish acknowledged.
  packetId: 1
Publish acknowledged.
  packetId: 2
Send message on MQTT
Publish acknowledged.
  packetId: 3
Publish acknowledged.
  packetId: 4
Send message on MQTT
Publish acknowledged.
  packetId: 5
Publish acknowledged.
  packetId: 6
Send message on MQTT
Publish acknowledged.
  packetId: 7
Publish acknowledged.
  packetId: 8
Send message on MQTT
Publish acknowledged.
  packetId: 9
Publish acknowledged.
  packetId: 10
Send message on MQTT
Publish acknowledged.
  packetId: 11
Publish acknowledged.
  packetId: 12
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Publish acknowledged.
  packetId: 1
Publish acknowledged.
  packetId: 2
Send message on MQTT
Publish acknowledged.
  packetId: 3
Publish acknowledged.
  packetId: 4
Send message on MQTT
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Publish acknowledged.
  packetId: 1
Publish acknowledged.
  packetId: 2
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Publish acknowledged.
  packetId: 1
Publish acknowledged.
  packetId: 2
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Publish acknowledged.
  packetId: 1
Publish acknowledged.
  packetId: 2
Send message on MQTT
Publish acknowledged.
  packetId: 3
Publish acknowledged.
  packetId: 4
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Publish acknowledged.
  packetId: 1
Publish acknowledged.
  packetId: 2
Send message on MQTT
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Send message on MQTT
Disconnected from MQTT.
Connecting to MQTT...
Connected to MQTT.
Session present: 0
Send message on MQTT
Но если поставить QoS 1 или 0 то сразу всё хорошо работает. Может на 100 с лишним сообщением переподключиться. А пвот если остановить службу брокера и запустить из командной строки брокера, то с QoS 2 все работает хорошо, даже если добавить больше сообщений на отправку, изредка только переподключается когда отправит больше 100 сообщений. Почему так происходит? Когда запущен через службу, то только одно сообщений с QoS 2 отправляет без проблем, добавляем больше двух подрят, то происходит такая ерунда, но когда запускаем через командную строку, то всё нормально отрабатывает!
 

notturno

New member
Господа всем доброго времени суток. Прошу помочь советом, натолкнуть на мысль куда смотреть.
Есть такая для меня проблемка связанная с работой mqtt.
Суть заключается в том, что есть несколько esp8266 которыми я управляю по mqtt. Что-то включаю, получаю какие-то данные и т.п. Все хорошо, но вот нюанс!
После перезагрузки сервера, некоторые esp8266 получают сообщение и вследствие чего включают какую-либо нагрузку или же отправляют сообщение в телеграмм и т.д.
Причем некоторые не все, есть esp которые этого не делают, что очень хорошо :)
Я не пойму куда копать, дело в программах для esp или-же серверная составляющая, что то с настройками ...
Что я использую:
Raspberry PI3 B+
Raspian
mqtt mosquitto
Node-Red

Что касается "QOS" на всех esp стоит приоритет "2" что до "Retain" - эта опция выключена.

p.s. в голову не лезет с чего начать, в чем нужно разобраться ...
 

notturno

New member
Господа всем доброго времени суток. Прошу помочь советом, натолкнуть на мысль куда смотреть.
Есть такая для меня проблемка связанная с работой mqtt.
Суть заключается в том, что есть несколько esp8266 которыми я управляю по mqtt. Что-то включаю, получаю какие-то данные и т.п. Все хорошо, но вот нюанс!
После перезагрузки сервера, некоторые esp8266 получают сообщение и вследствие чего включают какую-либо нагрузку или же отправляют сообщение в телеграмм и т.д.
Причем некоторые не все, есть esp которые этого не делают, что очень хорошо :)
Я не пойму куда копать, дело в программах для esp или-же серверная составляющая, что то с настройками ...
Что я использую:
Raspberry PI3 B+
Raspian
mqtt mosquitto
Node-Red

Что касается "QOS" на всех esp стоит приоритет "2" что до "Retain" - эта опция выключена.

p.s. в голову не лезет с чего начать, в чем нужно разобраться ...

В общем разобрался и исправил, возможно кому-то пригодится решение.
Я удалил топики и создал новые без "Retain" и перестало отправлять после перезагрузки.
Все дело в том, что когда пишу программы, тестирую, экспериментирую и т.д. и поставил "retain" потом убрал. А вот топик который сохранился на москито он с функцией "retain" сохранился и ничего уже не сделать. то-есть создавши новый топик все решило!
 

edw

New member
Mosquitto хранит базу топиков с их статусами при условии, что в конфиге установлено persistence true. Топики с Retain статусом публикуются автоматически при загрузке брокера либо при подключении клиента.
 

notturno

New member
Mosquitto хранит базу топиков с их статусами при условии, что в конфиге установлено persistence true. Топики с Retain статусом публикуются автоматически при загрузке брокера либо при подключении клиента.
Действительно в конфиге прописано "persistence true"! Получается что при первом получении сообщения с параметром retain - true или false сервер этот параметр запоминает и даже если произвести изменение в издателях, то он все равно будет первое полученное значение принимать за параметр?
Если изменить "persistence true" на "persistence false" то retain в принципе перестанет учитываться - любое значение? Или же только те, которые retain true?
 

edw

New member
Если изменить "persistence true" на "persistence false"
то брокер перестанет сохранять базу топиков, что с retain, что без retain и в вашем случае это помогло бы вырубить назойливые retain сообщения, которые приходили сразу после перезагрузки.
 
Сверху Снизу