MQTT2 - show traffic geht nicht

Begonnen von Nobbynews, 16 Juli 2023, 11:42:17

Vorheriges Thema - Nächstes Thema

Nobbynews

Hallo zusammen,

ich habe da mal eine Frage:
In ein und dem gleichen Browser-Fenster (Firefox 115.0.2, 64-Bit) funktioniert beim MQTT2-Server die Anzeige von show-traffic nicht. Allerdings klappt die Anzeige bei einem MQTT2-Client ohne jegliche Probleme.

MQTT2-Server ist:
FVERSION   00_MQTT2_SERVER.pm:0.276540/2023-06-04
MQTT2-Client ist:
FVERSION   00_MQTT2_CLIENT.pm:0.276540/2023-06-04
List vom MQTT2-Server:
define MQTT2_Server MQTT2_SERVER 1883 global
attr MQTT2_Server autocreate simple
attr MQTT2_Server icon mqtt_broker
attr MQTT2_Server keepaliveFactor 0
attr MQTT2_Server room 10_I/O-Geräte
#   CONNECTS   1260
#   Clients    :MQTT2_DEVICE:MQTT_GENERIC_BRIDGE:
#   ClientsKeepOrder 1
#   DEF        1883 global
#   FUUID      5e9286d3-f33f-8873-1634-d145de77bc430a0a
#   FVERSION   00_MQTT2_SERVER.pm:0.276540/2023-06-04
#   NAME       MQTT2_Server
#   NR         304
#   PORT       1883
#   SERVERSOCKET
#   STATE      Initialized
#   TYPE       MQTT2_SERVER
#   eventCount 4169
#   MatchList:
#     1:MQTT2_DEVICE ^.
#     2:MQTT_GENERIC_BRIDGE ^.
#   READINGS:
#     2023-07-16 11:29:03   lastPublish     pTrack:1
#     2023-07-16 11:02:31   nrclients       20
#     2023-07-16 11:12:42   state           Initialized
#   clients:
#     MQTT2_Server_192.168.2.207_48692 1
#     MQTT2_Server_192.168.2.220_60797 1
#     MQTT2_Server_192.168.2.221_57822 1
#     MQTT2_Server_192.168.2.222_58209 1
#     MQTT2_Server_192.168.2.224_65266 1
#     MQTT2_Server_192.168.2.226_53834 1
#     MQTT2_Server_192.168.2.226_58926 1
#     MQTT2_Server_192.168.2.229_27453 1
#     MQTT2_Server_192.168.2.230_18217 1
#     MQTT2_Server_192.168.2.232_11244 1
#     MQTT2_Server_192.168.2.233_19020 1
#     MQTT2_Server_192.168.2.239_10571 1
#     MQTT2_Server_192.168.2.242_18506 1
#     MQTT2_Server_192.168.2.243_20532 1
#     MQTT2_Server_192.168.2.247_16964 1
#     MQTT2_Server_192.168.2.46_64373 1
#     MQTT2_Server_192.168.2.59_44068 1
#     MQTT2_Server_192.168.2.63_59393 1
#     MQTT2_Server_192.168.2.64_62440 1
#     MQTT2_Server_192.168.2.85_50870 1
#
setstate MQTT2_Server 2023-07-16 11:29:03 lastPublish pTrack:1
setstate MQTT2_Server 2023-07-16 11:02:31 nrclients 20
setstate MQTT2_Server 2023-07-16 11:12:42 state Initialized


Ideen, woran es liegen kann??

Norbert

rudolfkoenig

Ich habe gerade keine Probleme, habs mit "mosquitto_pub -t hello -m world" getestet.
Funktioniert es im Inkognito-Fenster? Da werden keine Browser-Plugins geladen.
Sieht man was in der JavaScript-Console?

Nobbynews

#2
Zitat von: rudolfkoenig am 16 Juli 2023, 11:54:33Funktioniert es im Inkognito-Fenster? Da werden keine Browser-Plugins geladen.
Nein.
Zitat von: rudolfkoenig am 16 Juli 2023, 11:54:33Sieht man was in der JavaScript-Console?
Leider nicht viel:
Zitat12:09:45.625 12:09:45.625 Loading script /fhem/pgm2/console.js fhemweb.js:610:13
12:09:45.662 12:09:45.663 Event monitor is starting! fhemweb.js:610:13
12:09:45.778 12:09:45.778 FW_cmd:/fhem?cmd=%7BMQTT2_SERVER_addToFeedList('MQTT2_Server'%2C1)%7D&XHR=1 fhemweb.js:610:13
12:09:46.681 12:09:46.682 ERRMSG:< fhemweb.js:610:13
Sonst kommt nichts. Die Schaltbefehle funktionieren aber. Der Traffic lässt sich z.B. über MQTT Explorer verfolgen.

In der Konsole zum MQTT2-Client wird der Traffic angezeigt.

rudolfkoenig

Weitere (letzte?) Hypothese: es sind zu viele Tabs mit FHEMWEB offen: ein Browser oeffnet maximal 6 Verbindungen zu einer Seite.

Nobbynews

Zitat von: rudolfkoenig am 16 Juli 2023, 15:21:09Weitere (letzte?) Hypothese: es sind zu viele Tabs mit FHEMWEB offen: ein Browser oeffnet maximal 6 Verbindungen zu einer Seite.
In allen von mir benutzen Browsern habe ich den Cache gelöscht, Cookies gelöscht usw.
Das device habe ich gelöscht und neu angelegt.
Leider alles ohne Erfolg.
Egal welchen Browser ich auch nehme, Firefox, Edge oder Chrome, es wir partout weiterhin kein traffic angezeigt.
Im MQTT2-Client geht es ja ohne Probleme und ich gehe mal davon aus, dass hinter beiden Aufrufen der gleiche Mechanismus steckt.
Also irgendetwas ist bei mir anscheined ziemlich im Argen.

betateilchen

https://forum.fhem.de/index.php?topic=134090.0

Offenbar bin ich doch nicht der Einzige, der ein (ähnliches) Problem mit der Anzeige des MQTT traffics hat.
Danke!
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

alias2006

Wie sieht denn die Lösung für dieses Problem aus. Das Problem wurdenur gemeldet, aber es gibt keine beschriebene Lösung. Ich habe für fhem update durchgeführt, auch mit dem neuesten System klappt es bei mir nicht. ich habe es mit Firefox und Chrome auf linux ausprobiert, auf meinem iPad mit Firefox, Chrome,Safari, Dolfin, Opera. Nirgendwo krieg ich den traffic. Da es bei keinem der Browser funktioniert, kann es nur an fhem liegen, das auf dem Rasperry Pi 4 Model B Rev. 1.4 mit Debian Bookworm läuft. Kann jemand helfen?
Raspberry, Fritz, Qnap, it, Homatic, Viessmann, Netatmo, solaredge,Sonnen, shellies, PV Forecast, powerfox, usw.

JWRu

Funktioniert bei mir auch nicht.
Ich benutze jetzt den MQTT Explorer: https://mqtt-explorer.com
ZBox; RasPi 3B; RasPi Zero W; Homematic; Z-Wave; EnOcean, Shelly; DuoFern; Oregon- und Bresser-Sensoren; Steuerung Viessmann-Heizung; ESP32 und ESP8266 über MQTT; Arduino

alias2006

Den Explorer zu nutzen ist ja ganz schön und gut, da sehe ich aber nur was alles von/zu dem MQTT Service der Maschine ankommt/rausgeht. Ich seh aber nicht was nur fhem an MQTT sendet und empfängt. Insofern wäre der MQTT2 traffic doch interessant.
Raspberry, Fritz, Qnap, it, Homatic, Viessmann, Netatmo, solaredge,Sonnen, shellies, PV Forecast, powerfox, usw.

frober

#9
Ich habe das Problem auch, aber sporadisch funktioniert es.
D.h. wenn ich den Traffic Monitor immer wieder neu öffne funktioniert es irgendwann. Beim erneuten Öffnen funktioniert es wieder nicht mehr.

Unabhängig vom Browser (Chrome und Firefox auf Android, mobile oder Desktop Ansicht).
Auch beim Silk Browser auf einem älteren Amazon Fire Tablet das gleiche.

Edit:
Mit Edge auf Win10 funktioniert es besser, aber auch nicht zuverlässig. Chrome auf Win10 ist genauso zickig wie auf Android.
Gefühlt war auch Firefox auf Android etwas besser.
Raspi 3b mit Raspbian Bullseye und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

rudolfkoenig

Ich habe "Show MQTT traffic" jetzt mit einem MQTT2_SERVER und etlichen Clients (Chrome@linux, Firefox@linux, Safari@iOS/26, Chrome@Android/16, Chrome@Windows) getestet, und sehe keine Probleme.
Ich kriege die MQTT-Nachrichten in allen Clients (gleichzeitig) angezeigt.
Brauche mehr Info bzw. einen "Angriffspunkt", bin z.Zt. ratlos.

Guybrush

Ich hab mir das gerade mal angeschaut, weil ich auch das Problem bei mir hab. Hat mich jetzt zwar nicht so gestört, weil ich die mosquitto tools normalerweise nutze, aber doof ists schon. Für mich sieht das nach einem typischem race condition Problem aus:

Beim klicken auf show traffic passiert nach meiner Feststellung folgendes:
1. console.js schließt die bisherige FHEMWEB-Verbindung
2. Der neue Inform-/Traffic-Kanal wird erst nach 1000 ms gestartet
3. Der MQTT-Feeder wird aber bereits nach 100 ms aktiviert. Aktuelles console.js
4. Kommt während der 900-ms-Lücke eine MQTT-Nachricht, findet 00_MQTT2_SERVER.pm noch keinen passenden Inform-Kanal und löscht den Eintrag sofort wieder aus .feedList

Deswegen dürfte show traffic bei wenig traffic funktionieren, auf höher frequentierten hingegen nicht (mehr). Das erklärt auch, warum es sporadisch mal funktioniert... Wenn man den Monitor startet und dann die erste MQTT Nachricht innerhalb der ersten 1-2 Sekunden eintrifft geht es nicht, sonst schon

Ich würde die www/pgm2/console.js daher wie folgt patchen:
diff --git a/www/pgm2/console.js b/www/pgm2/console.js
--- a/www/pgm2/console.js
+++ b/www/pgm2/console.js
@@ -4,2 +4,3 @@ FW_version["console.js"] = "$Id$";
 var consConn;
 var consName="#console";
+var consReadyFn;
@@ -130,17 +131,27 @@ consFill()
    consConn = new WebSocket(loc.replace(/[&?].*/,'')
                                .replace(/^http/i, "ws")+query);
+    consConn.onopen = function() {
+      // Aktiviert optionale Feeder erst nach der serverseitigen Inform-Registrierung.
+      if(consReadyFn)
+        consReadyFn();
+    };
    consConn.onclose =
    consConn.onerror =
    consConn.onmessage = consUpdate;
 
  } else {
    if(consConn) {
      consConn.onreadystatechange = undefined;
      consConn.abort();
    }
    consConn = new XMLHttpRequest();
    consConn.open("GET", loc+query, true);
-    consConn.onreadystatechange = consUpdate;
+    consConn.onreadystatechange = function(evt) {
+      // Status 2 bestaetigt beim HTTP-Longpoll den aufgebauten Inform-Kanal.
+      if(consConn.readyState == 2 && consReadyFn)
+        consReadyFn();
+      consUpdate(evt);
+    };
    consConn.send(null);
 
  }
@@ -153,9 +164,12 @@ consFill()
 }
 
 function
-consStart()
+consStart(readyFn)
 {
+  // Bewahrt den Callback auch fuer einen automatischen Neuaufbau der Verbindung auf.
+  consReadyFn = readyFn;
+
  if($(consName).length != 1)
    return;
 
  if($("a#eventFilter").length)
@@ -437,12 +451,12 @@ cons4dev(screenId, filter, feedFn, devName)
        .height($("#content").height()/2-20)
        .css({overflow:"auto"});
      $(screenId+">a").html($(screenId+">a").html().replace("Show", "Hide"));
      FW_closeConn();
-      consStart();
-      // Leave time for establishing the connection, else the "feeder" may
-      // clear the flag
-      setTimeout(function(){ FW_cmd(cmd) }, 100);
+      consStart(function() {
+        // Registriert den MQTT-Feeder erst am nachweislich geoeffneten Inform-Kanal.
+        FW_cmd(cmd);
+      });
 
      $(screenId+" .reset").click(function(){ $(consName+" table").html("") });
      $(screenId+" .filter").click(function(){
        $('body').append(
@@ -472,6 +486,8 @@ cons4dev(screenId, filter, feedFn, devName)
      });
 
    } else {
+      // Verhindert eine erneute Feeder-Aktivierung durch einen spaeten Verbindungsaufbau.
+      consReadyFn = undefined;
      FW_cmd(cmd);
      $(consName).remove();
      $(screenId+">a").html($(screenId+">a").html().replace("Hide", "Show"));

Damit gehts bei mir wieder  8)

frober

Danke @Gaybrush,

dein Patch funktioniert auch bei mir. Auf allen getesteten Browsern und Betriebssystemen.
Raspi 3b mit Raspbian Bullseye und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

TomLee

@Guybrush: Mein verwendetes Modell schlägt zwei kleine Änderungen an dem Patch vor:

1. typeof-Prüfung für den Callback (nötig)

console.js endet mit

window.onload = consStart;

und 01_FHEMWEB.pm bindet console.js auf der Event-Monitor-Seite als normales <script src=...> ein (bei mir Zeile 2685, im Zweig "style eventMonitor"). Dort wird consStart beim Laden also mit dem Load-Event als erstem Argument aufgerufen. Mit

consReadyFn = readyFn;

landet damit ein Event-Objekt in consReadyFn. Das ist truthy, aber keine Funktion — der Aufruf in onopen wirft dann im "use strict"-Modus einen TypeError.

Fatal ist es nicht: consUpdate hängt separat an onmessage, der Event Monitor arbeitet weiter. Es steht aber bei jedem Verbindungsaufbau und jedem Reconnect eine unbehandelte Ausnahme in der Browser-Konsole, und das auf jeder Event-Monitor-Seite, also auch bei allen, die mit MQTT2 gar nichts zu tun haben. Vorschlag:

consReadyFn = (typeof readyFn == "function") ? readyFn : undefined;

2. onopen beim Abräumen mitnullen (kosmetisch)

In consFill werden beim Entkoppeln des alten Sockets onclose, onerror und onmessage genullt, onopen aber nicht. Folgenlos, weil close() auf einen noch verbindenden Socket kein onopen mehr auslöst — der Symmetrie halber würde ich es trotzdem ergänzen:

    if(consConn) {
      consConn.onopen =
      consConn.onclose =
      consConn.onerror =
      consConn.onmessage = undefined;
      consConn.close();
    }



Und erklären warum es auf einem ruhigen Testsystem praktisch immer funktioniert so:

Zur Reproduzierbarkeit

Der entscheidende Punkt ist, dass 00_MQTT2_SERVER.pm die Feed-Liste bei jeder einzelnen eintreffenden Nachricht prüft und ungültige Einträge stillschweigend verwirft:

my $cl = $FW_id2inform{$fwid};
if(!$cl || !$cl->{inform}{filter} || $cl->{inform}{filter} ne '^$') {
  delete($fl->{$fwid});
  next;
}

Damit hängt alles am Zufall: Kommt während der von dir beschriebenen Lücke auch nur eine Nachricht herein, ist die Registrierung weg — ohne Fehlermeldung, ohne Logeintrag. Kommt keine, läuft der Monitor anschließend dauerhaft stabil. Auf einem ruhigen Broker funktioniert "Show MQTT traffic" also praktisch immer, auf einem mit regem Verkehr praktisch nie. Das dürfte erklären, warum sich das Problem auf Testsystemen nicht zeigen wollte.

Festnageln lässt es sich eindeutig. Bei geöffneter, aber leerer Konsole liefert

{ my $h=$defs{MQTT2_Server}{".feedList"};; $h ? "feedList: ".join(",",keys %$h) : "feedList: leer" }

ein "leer", während gleichzeitig

{ join("\n", map { $_." filter=".($FW_id2inform{$_}{inform}{filter} // "-")." type=".($FW_id2inform{$_}{inform}{type} // "-") } keys %FW_id2inform) }

sehr wohl einen lebenden Kanal mit filter=^$ und type=raw zeigt. Bei mir sah das im Fehlerfall so aus:

feedList: leer

1787243001.92815 filter=         type=status
1787229261.65442 filter=room=... type=status
1787316789.65783 filter=^$       type=raw     <-- die offene Konsole
1787307486.78416 filter=         type=status

Der Browser wartet also korrekt, nur der Server weiß nichts mehr von ihm. Am Feed-Mechanismus selbst ist nichts defekt — ich habe einen Longpoll-Client von der Shell an FHEMWEB gehängt, den Eintrag in .feedList gesetzt und darüber dauerhaft Traffic empfangen. Es ist ausschließlich die Reihenfolge.

Guybrush

klar, das war auch nur ein billiger workaround. Ich stimme dir aber zu, dass man das dann dirket sauber mit entsprechender prüfung integrieren sollte, wie von dir vorgeschlagen. Wenn man da schonmal rangeht... Das ist aber Rudis aufgabe dann ;)