[Nightly 0.8.0-2803] Node-Blue / mosquitto: No PUBACK received

Seit ich gestern auf das aktuelle Nightly umgestellt habe, häufen sich die Verbindungsprobleme mit meinem mosquitto Broker. Meine vorherige Version war auch das nighly (0.8.0-27xx). Dadurch gehen massiv mqtt-Nachrichten verloren.

10/10/19 11:59:08.551 Node-BLUE (1926): Node 5cf6d1d3.6e689: Warning: Connection to MQTT server closed.
10/10/19 11:59:13.551 Node-BLUE (1926): Node 5cf6d1d3.6e689: Error: No response received to packet: 3A090000506C66616C7365
10/10/19 11:59:13.551 Node-BLUE (1926): Node 5cf6d1d3.6e689: Warning: No PUBACK received.

Die Node ist meine mqtt-Broker Konfigurations-Node.

image

Das ist meine mosquitto.conf

# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example

pid_file /var/run/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

include_dir /etc/mosquitto/conf.d

password_file /etc/mosquitto/passwd
allow_anonymous false

Ich war vorher auf der 0.8.0-2731 vom 30.7.2019. Die gibt es aber leider nicht mehr in den Nightlies, daher gehe ich auf die 0.8.0-2735 zurück.

Und hoffe, das das System dann wieder läuft. :wink:

Und der Fehler bleibt. :frowning:

Ich habe einen nagelneuen Raspberry Pi 4 mit mosquitto broker aufgesetzt. Node-Blue habe ich dann umkonfigueriert, diesen zu benutzen.

Es gab exakt das gleiche Problem. @sathya, kannst du nachvollziehen, was zwischen 2731 und 2735 bezüglich mqtt passiert ist? Im Quellcode finde ich nichts, was darauf hindeutet.

Oder kann es sein, dass das Upgrade auf 2803 die mqtt-Nodes verändert hat, so dass diese nicht mehr zuverlässig funktionieren?

Ich habe das Problem weiter eingegrenzt und es tritt nur bei der mqtt-out Node auf.
Da das Downgrade nichts gebracht hat, bin ich jetzt wieder auf das aktuelle nightly 0.8.0-2808 gegangen.

Im aktuellen Quellcode (Zeilen 54-55) ist mir folgendes aufgefallen:

		settingsIterator = info->info->structValue->find("retain");
		if(settingsIterator != info->info->structValue->end()) _retain = (settingsIterator->second->stringValue == "true");

Meiner Ansicht nach, bedeutet das, dass _retain nur einen sinnvollen Inhalt hat, wenn retain in der Info-Struktur vorhanden ist. Ansonsten ist es undefiniert. Allerdings ist mein C-Wissen etwas eingerostet, und das mag auch irrelevant sein.

@sathya, ich bin dem Problem auf den Grund gekommen. :smiley:

Ich konnte es auf meine Heizungssteuerung eingrenzen, diese habe ich erst letztens wieder eingeschaltet, daher ist es nicht vorher aufgefallen. :wink:

Die folgende Logik aus der mqtt-out-node, Zeilen 98-106, verhält sich nicht so wie in der Hilfe beschrieben:

	std::string topic;
	auto messageIterator = message->structValue->find("topic");
	if(messageIterator != message->structValue->end()) topic = messageIterator->second->stringValue;
	else topic = _topic;

	bool retain;
	messageIterator = message->structValue->find("retain");
	if(messageIterator != message->structValue->end()) retain = messageIterator->second->booleanValue;
	else retain = _retain;

In der Dokumentation ist beschrieben, dass man topic/retain leer lassen soll, wenn man das topic/retain über die Message-Struktur setzen will. So wie ich das interpretiere, wird aber immer das topic aus der Message genommen, falls es vorhanden ist. Nur wenn in der Message kein topic ist, wird das aus der nodeinfo-Struktur genommen.

Der Code müsste meiner Ansicht nach so lauten. damit es wie in der Hilfe beschrieben steht funktioniert. Es fehlt noch eine Prüfung, ob in der Message der Topic gesetzt ist und etwas Fehlerhandling. :

	std::string topic;
	auto messageIterator = message->structValue->find("topic");
	auto settingsIterator = info->info->structValue->find("topic");
	if(settingsIterator != info->info->structValue->end()) topic = messageIterator->second->stringValue;
	else topic = _topic;

	bool retain;
	messageIterator = message->structValue->find("retain");
	settingsIterator = info->info->structValue->find("retain");
	if(settingsIterator != info->info->structValue->end()) retain = messageIterator->second->booleanValue;
	else retain = _retain;

Durch einen dummen Zufall war bei meiner Heizungssteuerung in einigen Fällen das topic = "" und genau das bringt die Konfigurationsnode zum Absturz und Verlust der Verbindung zum Broker. Alles was auch an dieser Konfigurationsnode hängt funktioniert dann ca. 10-20 Minuten nicht mehr.

2 Likes

Hallo @job,

die entsprechende Änderung habe ich gepushed. Vielen Dank! Aber bist du dir sicher, dass das das Problem löst? Wenn es im Nachrichtenobjekt ein leerer String ist, sollte retain einfach false sein. Das dürfte der Verbindung nichts ausmachen…

Viele Grüße

Sathya

2 Likes

Nein, ich denke das leere topic war das Problem. Die Änderung am _retain spielt eigentlich keine Rolle, dient nur der Uniformität.

Ah, zu schnell gelesen :roll_eyes:. Ich war total auf das retain fokussiert. Das erklärt tatsächlich das Problem. Ist im nächsten Nightly ebenfalls gefixt.

1 Like