"Client FHEM disconnected due to malformed packet"

Begonnen von Master_Nick, 06 September 2021, 21:26:43

Vorheriges Thema - Nächstes Thema

Beta-User

...und noch zwei  Nachbrenner-Gedanken zum Modul:

  my $clientId = AttrVal($name,"client-id",undef);

Kommt mir komisch vor. Neulich hatten "wir" es irgendwo anders davon, dass das Protokoll zwingend eine ID fordert. Am Ende scheint die immer da zu sein, allerdings ist mir vor obigem Hintergrund nicht klar, wo die herkommt.

Was MQTT_QOS_AT_MOST_ONCE angeht, war ich erst unsicher, aber anscheinend wird das mehr oder weniger überall (set publish und set-Anweisungen an MQTT_DEVICE) per default gesetzt. Soweit ok. Wenn aber die "Speicherlogik" geändert wird, müßte/sollte/könnte es eine Obergrenze geben? (Ich habe nicht geprüft, ob DEVICE das auch noch puffert und ggf. gegen aktuelle Werte tauscht, wenn erkannt wird, das das IO weg ist).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

hexenmeister

Zitat von: Beta-User am 11 September 2021, 14:03:35
Das deckt sich nicht mit meinem Verständnis: Wenn, dann müßte es irgendein Unterhash von dem sein, was sich aus my $message = Net::MQTT::Message->new(%msg);
ergibt. Vermutlich könnte man da auch auf die "inneren Werte" zugreifen, aber das hatte ich bei meinem Vorschlag übersehen...
Ich verstehe nicht, was Du meinst. new erstellt mit bless doch nur eine Art (Perl) Object, was auch nur ein Hash ist. Hat in diesem Fall keine interne Strukturen. In diesem Hash ist einfach alles, was man da rein gibt. U.a. auch qos. Und msg selbst liegt in dem (device)hash->{messages}.

Zitat von: Beta-User am 11 September 2021, 14:03:35
Was sub send_publish() angeht - müßte das nicht so starten:
sub send_publish($@) {
  my ($hash,%msg) = @_;
  if (!$msg{qos}) {

Würde in diesem Fall ja auch funktionieren, da MQTT_QOS_AT_MOST_ONCE gleich Nulöl ist, aber ein direkter Vergleich ist verständlicher.

Zitat von: Beta-User am 11 September 2021, 14:03:35
Na ja, vielleicht sollte man es wirklich mittelfristig einmotten, aber wir bräuchten dann einen Plan, wie das gehen soll, damit niemand aus allen Wolken fällt.
Ja, stimmt. Könnte man so, wie Du schreibts auch machen.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

hexenmeister

Zitat von: Beta-User am 11 September 2021, 15:53:39
  my $clientId = AttrVal($name,"client-id",undef);

Kommt mir komisch vor. Neulich hatten "wir" es irgendwo anders davon, dass das Protokoll zwingend eine ID fordert. Am Ende scheint die immer da zu sein, allerdings ist mir vor obigem Hintergrund nicht klar, wo die herkommt.

Dokuj meint dazu:
ZitatA Server MAY allow a Client to supply a ClientId that has a length of zero bytes, however if it does so the Server MUST treat this as a special case and assign a unique ClientId to that Client. It MUST then process the CONNECT packet as if the Client had provided that unique ClientId [MQTT-3.1.3-6].

If the Client supplies a zero-byte ClientId, the Client MUST also set CleanSession to 1 [MQTT-3.1.3-7].

If the Client supplies a zero-byte ClientId with CleanSession set to 0, the Server MUST respond to the CONNECT Packet with a CONNACK return code 0x02 (Identifier rejected) and then close the Network Connection [MQTT-3.1.3-8].

If the Server rejects the ClientId it MUST respond to the CONNECT Packet with a CONNACK return code 0x02 (Identifier rejected) and then close the Network Connection [MQTT-3.1.3-9].
Allerdiongs nur, wenn CleanSession gesetzt ist, was wir anscheinend nie tun. Somit hast Du recht, sollte eiug. nicht funktionieren.

Zitat von: Beta-User am 11 September 2021, 15:53:39
Was MQTT_QOS_AT_MOST_ONCE angeht, war ich erst unsicher, aber anscheinend wird das mehr oder weniger überall (set publish und set-Anweisungen an MQTT_DEVICE) per default gesetzt. Soweit ok. Wenn aber die "Speicherlogik" geändert wird, müßte/sollte/könnte es eine Obergrenze geben? (Ich habe nicht geprüft, ob DEVICE das auch noch puffert und ggf. gegen aktuelle Werte tauscht, wenn erkannt wird, das das IO weg ist).
Ja, QOS0 ist Standard. Was würdest Du mit der Speicherlogik anders tun? DEVICE macht damit, meine ich, gar nichts und schon gar kein Austausch.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

Beta-User

Zitat von: hexenmeister am 11 September 2021, 17:55:49
Ich verstehe nicht, was Du meinst. new erstellt mit bless doch nur eine Art (Perl) Object, was auch nur ein Hash ist. Hat in diesem Fall keine interne Strukturen. In diesem Hash ist einfach alles, was man da rein gibt. U.a. auch qos. Und msg selbst liegt in dem (device)hash->{messages}.
Danke für die Erläuterung. Das mit den Objekten muss ich dann wohl nochmal (bei Bedarf) vertiefen, ich hätte das jetzt als den Rückgabewert einer Umwandlung aufgefasst.
Aber dann kann man auch direkt auf "ispub" zurückgreifen, weil das als "message_type" dann ja auch mit da drin steckt, und man das nur rausholen muss, wenn die Gegenstelle noch nicht quittiert hat.

Zitat
Würde in diesem Fall ja auch funktionieren, da MQTT_QOS_AT_MOST_ONCE gleich Null ist, [...]
:o ...Denkfehler meinerseits, sorry.!
Streich es von der Liste ::) .

Zitat von: hexenmeister am 11 September 2021, 18:10:02
Allerdiongs nur, wenn CleanSession gesetzt ist, was wir anscheinend nie tun.
Dann einfach "$name" als Rückgabe aus der AttrVal-Abfrage? (Just to be sure...) MQTT2_SERVER macht zwar von "may" Gebrauch und läßt das auch zu, führt dann aber ohne ClientID  z.B. kein "autocreate" aus (wie auch immer man dazu steht, deine Skepsis hat durchaus auch eine gewisse Berchtigung :D ). Andere Server-Typen (oder future mosquitto) sind da evtl. nicht so tolerant...

Zitat
Ja, stimmt. Könnte man so, wie Du schreibts auch machen.
Eilt ja nicht, erst kommt die Reparatur :) .
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

hexenmeister

Zitat von: Beta-User am 11 September 2021, 18:22:41
Danke für die Erläuterung. Das mit den Objekten muss ich dann wohl nochmal (bei Bedarf) vertiefen, ich hätte das jetzt als den Rückgabewert einer Umwandlung aufgefasst.
Aber dann kann man auch direkt auf "ispub" zurückgreifen, weil das als "message_type" dann ja auch mit da drin steckt, und man das nur rausholen muss, wenn die Gegenstelle noch nicht quittiert hat.
Die Objekte in Perl sind mir (als Java-Entwickler) auch recht suspekt. Bin mir da auch oft unsicher, was alles da geht und was nicht ;D
Auf ispub kann man da, wie du ja auch gemacht hast, einfach zugreifen mit $msg->{ispub};

Zitat von: Beta-User am 11 September 2021, 18:22:41
Dann einfach "$name" als Rückgabe aus der AttrVal-Abfrage? (Just to be sure...) MQTT2_SERVER macht zwar von "may" Gebrauch und läßt das auch zu, führt dann aber ohne ClientID  z.B. kein "autocreate" aus (wie auch immer man dazu steht, deine Skepsis hat durchaus auch eine gewisse Berchtigung :D ). Andere Server-Typen (oder future mosquitto) sind da evtl. nicht so tolerant...
Da habe ich auch schon überlegt, was ich in diesem Fall nehmen soll... Evtl. wirklich etwas wie "fhem_client_$name", oder FUUID... Vlt. sogar FUUID besser.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

Beta-User

Zitat von: hexenmeister am 11 September 2021, 19:08:47
Auf ispub kann man da, wie du ja auch gemacht hast, einfach zugreifen mit $msg->{ispub};
Achtung: Das habe ich vorher erst in send.* reingeknödelt, im originalen Hash heißt das anders und könnte dann ggf. auch anders (im Connect-Fall) ausgewertet werden. Deswegen der Hinweis vorhin, dass ich meine, der letztgenannte Weg wäre effizienter (wenn es denn geht...)

Zitat
Da habe ich auch schon überlegt, was ich in diesem Fall nehmen soll... Evtl. wirklich etwas wie "fhem_client_$name", oder FUUID... Vlt. sogar FUUID besser.
Evtl. wäre ja grade wegen der "autocreate"-Geschichte auch "" die beste Lösung. FUUID hatte ich auch schon überlegt, aber wieder verworfen. Müßte man auch holen und wäre nicht "unique", falls jemand auf den Gedanken kommt, mehrere Verbindungen aufzumachen (aus welchen Gründen auch immer...). Die ID ist meinem Gefühl nach auch nicht zur größeren Verbreitung gedacht.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

hexenmeister

Zitat von: Beta-User am 11 September 2021, 19:19:34
Achtung: Das habe ich vorher erst in send.* reingeknödelt, im originalen Hash heißt das anders und könnte dann ggf. auch anders (im Connect-Fall) ausgewertet werden. Deswegen der Hinweis vorhin, dass ich meine, der letztgenannte Weg wäre effizienter (wenn es denn geht...)
Jeeeetzt (erst) ist der Groschen gefallen. :/ Habe Deine Lösung genommen, da es funktioniert hat (klar, ist ja immer false) und dachte, in der Message existiert dieser Flag schon... Dann muss das natürlich so sein:
$msg->{dup} = $msg->message_type == MQTT_PUBLISH;
In diesem Fall ist das ein Methodenaufruf, Message.pm Definiert das so:
sub message_type { shift->{message_type} }
Jedoch scheinen die einzelnen Subklassen das einfach stumpf zu überschreiben:

sub message_type {
  3
}

Somit bin ich nicht sicher, dass $msg->{message_type} immer korrekt befüllt wird.

Zitat von: Beta-User am 11 September 2021, 19:19:34
Evtl. wäre ja grade wegen der "autocreate"-Geschichte auch "" die beste Lösung. FUUID hatte ich auch schon überlegt, aber wieder verworfen. Müßte man auch holen und wäre nicht "unique", falls jemand auf den Gedanken kommt, mehrere Verbindungen aufzumachen (aus welchen Gründen auch immer...). Die ID ist meinem Gefühl nach auch nicht zur größeren Verbreitung gedacht.
Wenn man UID des IODevices niummt, sollte doch eindeutig sein?
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

Beta-User

hehehe, jetzt ist dann auch bei mir der Groschen gefallen, auf was sich UUID bezieht - gute Lösung mit dem Internal :) .
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

hexenmeister

Könnte man dann so machen:
my $clientId = AttrVal($name,"client-id", $hash->{'FUUID'}});
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

Beta-User

Hehe, ... ja, wenn man doppelte Quotes mag und "normale" Hash-Labels in einfachen...

*duckundweg*
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Lothar64

Hallo,
kaum ist man ein paar Stunden weg, schon geht es hier richtig ab.
Vielen vielen Dank für eure Mühe, die ihr in dieses alte Modul steckt, wobei alt ja nicht schlecht heißt. Kann auch ausgereift bedeuten  :D .
Ich habe die Version von Beta-User aus Antwort 37 mal geladen. Sie funktioniert auch.
Aus den Perl Diskussionen halte ich mich schön raus, da ist zu hoch für mich als C Entwickler.
Ich werde mich noch mal etwas tiefer in das MQTT Protokoll einlesen. Aber eine Frage vorab. Warum sendet man Nachrichten zwei mal, die werden doch schon über TCP/IP abgesichert. Ein weiteres Update von Mosquitto könnte das ebenfalls nicht gefallen.


hexenmeister

Zitat von: Beta-User am 11 September 2021, 22:33:16
Hehe, ... ja, wenn man doppelte Quotes mag und "normale" Hash-Labels in einfachen...

*duckundweg*
>:( Als "Java-Mensch" vergesse ich so was ständig.

Besser?
my $clientId = AttrVal($name,'client-id', $hash->{FUUID});
:P
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

hexenmeister

Zitat von: Lothar64 am 11 September 2021, 22:34:28
Ich habe die Version von Beta-User aus Antwort 37 mal geladen. Sie funktioniert auch.
Ab morgen per Update wird eine funktionierende Version verteilt.

Zitat von: Lothar64 am 11 September 2021, 22:34:28
Ich werde mich noch mal etwas tiefer in das MQTT Protokoll einlesen. Aber eine Frage vorab. Warum sendet man Nachrichten zwei mal, die werden doch schon über TCP/IP abgesichert. Ein weiteres Update von Mosquitto könnte das ebenfalls nicht gefallen.
Naja, ich hoffe im Normalfall werden Nachrichten nicht zwei Mal gesendet.
Die fragliche Stelle ist für den Fall gedacht, wenn die Quittungen fehlen. So sieht das auch das Protokoll vor.
Alle gesendete Nachtrichten mit QOS>0 werden in einer Liste gehalten, beim Eingehen von Quittungen vom Server werden gespeichrte Nachrichten aus der Liste entfernt.
Bei Verlust der Verbindung, nach dem Reconnect, werden alle noch nicht bestätigte Nachrichten nochmal geschickt, diesmal mit dem DUP-Flag. Sollte (hoffentlich) in Übereinstimmung mit dem Protokoll sein.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

Lothar64

ZitatNaja, ich hoffe im Normalfall werden Nachrichten nicht zwei Mal gesendet.
In meinem Mosquitto log werden alle Subscribe Nachrichten nach einem connect zwei mal gesendet. Alle werden auch mittels Suback korrekt bestätigt. 

Beta-User

Zitat von: hexenmeister am 11 September 2021, 22:38:58Besser?
;D ...die Sonne geht über Java auf ;D ...

Zitat von: Lothar64 am 11 September 2021, 22:34:28
wobei alt ja nicht schlecht heißt. Kann auch ausgereift bedeuten  :D .
Ja, weiß nicht recht...

MQTT-classic (und MYSENSORS) sind an ein paar Stellen "an FHEM vorbei", was einer der Gründe war, warum Rudi MQTT2 entwickelt hat. Und der Code ist auch - na ja - irgendwie eigentlich "seit immer" kaum verändert - läuft ja.

Zitat
Warum sendet man Nachrichten zwei mal, die werden doch schon über TCP/IP abgesichert.
Wenn ich es richtig verstanden habe, ist der Grund schlicht und ergreifend der, dass es keinen Check gibt, ob der Broker verfügbar ist, bevor gesendet wird. Ansonsten müßte man eine 2. Queue haben... (@hexenmeister: Bin nicht sicher, ob das nicht auch z.B. die subscriptions  betrifft; sonst müßte man uU. noch mehr Statusinfos abfragen und sich den Start-Prozess ansehen...)
Das war jedenfalls das Zwischenergebnis, zu dem ich bis dato gekommen bin. Soviel dann zum "ausgereift"...

Um das aber klarzustellen: soweit ich das im Kopf habe, hat @hexenmeister die Module "nur" übernommen, weil er mit der "MQTT_GENERIC_BRIDGE" "sowieso" in MQTT unterwegs war und dann -mangels damals bestehender Alternativen - dann eben an den vorhandenen Code angedockt hat, an dem seit den Urzeiten kaum was passiert war (warum auch, lief ja soweit) ;D .
Da der Code aber "eigen" ist, ist es auch relativ schwer, da tiefer einzugreifen...

Will sagen: Danke, hexenmeister, dass du den Job machst!  ;D
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files