Ich habe eine kleine Verständnis Frage, ich dachte... Connect -> Publish -> close Tcp ... oder innerhalb der alive PingReq oder weitere Nachrichten offenbar ist mir der Broker sauer wenn man die TCP Verbindung einfach schließt und schmeißt den client einfach raus. Baut man die Verbindung wieder auf will er unbedingt ein Connect sonst macht er sie wieder zu. Connect -> publish -> disconnect -> close TCP ergibt kein Problem das dumme ist nur das der broker nun auch nicht mehr feststellt wenn der client fehlt. Ich dachte immer Mqtt kann mit halb offen Verbindungen umgehen. Das ganze wäre sau blöd da die TCP Verbindung immer offen sein müsste was extrem viel Strom verbraucht. Oder man muss den Client per disconnect abmelden. Dann kann aber auch nicht mehr festgestellt werden ob der Client noch am leben ist. Ich habe als Broker HiveMQ.
Marco H. schrieb: > Baut man die Verbindung > wieder auf will er unbedingt ein Connect sonst macht er sie wieder zu. Steht so im Standard: >> After a Network Connection is established by a Client to a Server, the >> first Packet sent from the Client to the Server MUST be a CONNECT Packet >> [MQTT-3.1.0-1]. > Connect -> publish -> disconnect -> close TCP > > ergibt kein Problem das dumme ist nur das der broker nun auch nicht mehr > feststellt wenn der client fehlt. Dazu gibt es Keep Alive und Will Message (und mit Retain Messages muss man eventuell auch noch rummachen). > Ich dachte immer Mqtt kann mit halb offen Verbindungen umgehen. Nein, MQTT kennt solche Feinheiten nicht. Eher im Gegenteil, es vermeidet sie. Keep Alive gibt es, weil halb-offene Verbindungen in vielen Umgebungen nicht zuverlässig erkannt werden können. Damit würde ein Broker eventuell nicht merken, dass ein Client schon längs weg ist. > Das ganze wäre sau blöd da die TCP Verbindung immer offen sein müsste Offen und am besten noch Keep Alive Pings. Nur ein sprechender Client ist ein lebender Client. > was extrem viel Strom verbraucht Was willst du hören. Es ist nun mal nicht so einfach wie es aussieht.
Das ist ja das Problem, Disconnect meldet den Client auch wirklich ab. Ohne die Will etc. zu versenden. Schließt man die Verbindung ohne Disconnect versendet der Broker die Will messages da er den Client unschön entfernt. Ich dachte man kann die Verbindung einfach sauber schließen(TCP disconnect) und nach Ablauf der keepalive wird der Client entfernt und somit die Will messages gesendet. Wenn man nicht ein PingReq Paket sendet, das aber nie eintritt wenn immer ein Connect packet nötig ist. Da dieses ja den keepalive neu startet. Den Client kann man anhand der ID ja erkennen unabhängig über welche Verbindung diese Daten sendet. Das offen halten von TCP overhead ist einfach sau blöd meiner Meinung. Wenn man einen Schalter hat der einen Status liefert bekommt man nie mit wenn dieser nicht funktioniert. So müsste dieser nach Ablauf der keepalive sich einmal melden. Sonst macht der broker mit der Will die Lampe im zweifel aus. Man kann zwar Daten auch mit dem disconnect senden aber dann muss der Empfänger selber den Zeitstempel prüfen um zu erkennen das keine Daten mehr kamen. Irrend wie macht es das ganze MQTT zum absurdum ...
Hallo, verstehe ich nicht. Natürlich muß ein Client sich beim Broker melden wenn der wissen will, daß dieser noch lebt. KeepAlive je nach Anwenung z.B. auf 15min setzen, alle 10 Minuten den Client wecken und ein Connect schicken und wieder schlafen gehen. Beim Schalten eben auch wecken, die Message schicken und schlafen gehen. Wie sonst soll ein Broker z.B. meinen tief schlafenden AVR erkennen? Gerade KeepAlive, LastWill, Qos-Modi usw. machen doch MQTT so einfach zu handhaben. Gruß aus Berlin Michael
Also der HiveMQ sendet keine Will Messages mehr wenn man den Client MQTT disconnected. Macht man die TCP Verbindung zu sendet dieser die Will Messages, da ohne MQTT disconnect offenbar der Broker von einen Fehler ausgeht. Genau hier liegt ja mein Problem, ich muss die TCP Verbindung offen halten. Müsste mal schauen ewt. kann man das in der config des HiveMQ beeinflussen.
:
Bearbeitet durch User
Marco H. schrieb: > Also der HiveMQ sendet keine Will Messages mehr wenn man den Client MQTT > disconnect. Steht so im Standard. Vielleicht solltest du den lesen. >> On receipt of DISCONNECT the Server: >> >> * MUST discard any Will Message associated with the current >> connection without publishing it, as described in Section >> 3.1.2.5 [MQTT-3.14.4-3]. > Macht man die TCP Verbindung zu sendet dieser die Will > Messages, da ohne MQTT disconnect offenbar der Broker von einen Fehler > ausgeht. Steht so im Standard. Vielleicht solltest du ... >> Situations in which the Will Message is published include, but are not >> limited to: >> >> * An I/O error or network failure detected by the Server. >> * The Client fails to communicate within the Keep Alive time. >> * The Client closes the Network Connection without first sending a >> DISCONNECT Packet. >> * The Server closes the Network Connection because of a protocol >> error. > Genau hier liegt ja mein Problem, ich muss die TCP Verbindung offen > halten. Ich beende dann hier meine Vorlesestunde aus dem Standard.
Aber das ist doch sau blöd ? Gerade für Batterie betriebene Geräte. Die müssen die Transportschicht immer offen halten oder sich abmelden. Womit sie aber nicht mehr überwacht werden können.
Hallo, Marco H. schrieb: > Also der HiveMQ sendet keine Will Messages mehr wenn man den > Client MQTT > disconnected. Macht man die TCP Verbindung zu sendet dieser die Will > Messages, da ohne MQTT disconnect offenbar der Broker von einen Fehler > ausgeht. Natürlich. LastWill wird ja auch gesnedet, wenn die Verbindung aus technischen Gründen verloren geht. Wenn der Client Disconnect meldet ist es ja seine Absicht, wenn er da was publishen will, kann er es ja vor dem Disconnect selber erledigen. > > Genau hier liegt ja mein Problem, ich muss die TCP Verbindung offen > halten. Müsste mal schauen ewt. kann man das in der config des HiveMQ > beeinflussen. Verstehe ich immernoch nicht. z.B. einer meiner Sensoren sendet alle 5 Minuten die Temperatur. Gäbe es jetzt noch einen Schalter, weckt der bein Öffnen oder Schließen den ESP und schickt seine MEssage. Dann geht der ESP wieder schlafen, damit bricht natürlich die TCP-Verbindung ab und die KeepAlive Zeit läuft. Entweder wecke ich jetzt den ESP vor Ende des gesetzten KeepAlive und melde mich, dann ist alles ok oder jemand klaut den Sensor und nach Ablauf der KeepAlive-Zeit schickt der Broker den LastWill raus. LastWill ist ein Fehlerfall, der eben genau die hinterlegte Meldung an die Abbonenten schickt, weil die Verbindung ungeplant abgebrochen ist. Ist doch Sinn des Ganzen. Gruß aus Berlin Michael
:
Bearbeitet durch User
Eben nicht sobald die TCP Verbindung ohne disconnect abbricht sendet der Broker die Will Messages ;) "steht doch im Protokoll " Dein Licht würde bei jeden Abbruch wieder ausgehen nur weil der Schalter durch eine Störung verschwindet. Wirklich durchdacht das ganze ...
Für deinen Temperatur Sensor würde das bedeuten das es immer 25° sind da du durch den disconnect nicht Festellen kannst wenn die letzten Daten kamen. Der Broker könnte per Will messages dem Empfänger einen Fehler senden. So muss der Empfänger selber prüfen wenn das letzte Telegramm kam. Von der keepalive deines Sensors weiß der aber nichts. Irrend wie sau blöd, da das MQTT die belange der Transportschicht nicht berücksichtigt. Tja und dein kleiner µP ist mit jeder TCP Verbindung die offen bleibt belastet. Auch der PC hat seine Begrenzten Ports > 1024. Wenn alle 5 min nur was kommt und hierzu die Verbindung offen zu halten ist wenig intelligent. So richtig blöd wenn man ein Mobilfunk denkt, verbraucht das richtig viel Strom. Als sich alle 5 min in Netz zu wählen um ein paar Daten zu versenden.
:
Bearbeitet durch User
Hallo, Marco H. schrieb: > Dein Licht würde bei jeden Abbruch wieder ausgehen nur weil der Schalter > durch eine Störung verschwindet. Wirklich durchdacht das ganze ... Warum solle das Licht ausgehen wenn der Schalter verschwindet? Der Schalter schickt Licht an und das Licht geht an. Der Schalter schickt Licht aus und das Licht geht aus. Wenn der Schalter verschwindet bleibt der letzte Status doch erhalten. LastWill schickt eine Message "Schalter weg". Darauf kann das Licht so reagiere, wie ich es geplant habe. Es passiert garnicht oder ich mache eine Signalled an der Lampe an, daß der Schalter nicht geht oder ich blinke 3x mit dem Licht oder usw. Die nötige Reaktion bleibt doch jedem Abonnenten überlassen und ich muß es festgelegt haben. Bei der Temperatu z.B. könnte LastWill einen Fehler melden und der Anzeigeclient zeit dann Striche an oder garkeine Temperatur oder... Warum sollte der Abonnent prüfen müssen, wann die letzte gültige Meldung kam? Der muß auf die möglichen Messages passend reagieren können. Wenn alle 5 Minuten eine neue Temperatur kommt reicht der Broker die weiter. Kommt bis zum Ableuf von KeepAlive (z.B. 7 Minuten) keine, schickt er den Fehler raus. Passend reagieren muß der Empfänger je nach dessen Anforderungen. >So richtig blöd wenn man ein Mobilfunk denkt, verbraucht das richtig >viel Strom. Als sich alle 5 min in Netz zu wählen um ein paar Daten zu >versenden. Der ESP braucht unter 1s zum Booten, WLAN-Connect, Connect zum Broker und versenden der Message. Dann geht er einfach wieder schlafen. Logischweise sind die Verbindungen weg wenn der ESP in den DeepSleep geht. Selbet ein Abonnent könnte nur alle 5 Minuten verbinden und nachschauen, per Retain würd er eine inzwischen eingegenage Message vom Brocker bekommen, selbst wenn der Publisher schon längst wieder schläft. Gruß aus Berlin Michael
Marco H. schrieb: > Connect -> publish -> disconnect -> close TCP > > ergibt kein Problem das dumme ist nur das der broker nun auch nicht mehr > feststellt wenn der client fehlt. Und wie soll er das feststellen, wenn du die TCP-Verbindung einfach so schließt? > Das ganze wäre sau blöd da die TCP Verbindung immer offen sein müsste > was extrem viel Strom verbraucht. Warum?
Anhand der keepalive, besser wäre es einen disconnect zu schaffen wo sich der Client nur halb abmeldet und die Keepalive weiter läuft. Bei offener TCP Verbindung werden immer wieder Daten hin und her geschoben. Die Hardware müsste in Betrieb bleiben um die Verbindung offen zu halten.
Hallo, Marco H. schrieb: > Anhand der keepalive, besser wäre es einen disconnect zu schaffen wo > sich der Client nur halb abmeldet und die Keepalive weiter läuft. KeepAlive läuft auf dem Broker und nur dort. Der Client setzt beim Connect nur die gewünschte KeepAlive-Zeit und die LastWill-Message. Wenn KeepAlive auf dem Broker abläuft weil sich der Client in dieser zeit nicht mehr gemeldet hat, sendet der broker den LastWill. MQTT wurde ja ursprünglich gerade deshalb entwickelt: kleine nötige Datenmengen und größtmögliche Sicherheit bei generell instabilen Verbindungen. Die Clients müssen nur einmal das gewünschte Verhalten beim Broker hinterlegen, dann kümmert dieser sich um diese Sachen. Gruß aus Berlin Michael
Naja von schlank kann keine Rede sein da dass ganze mit Strings funktioniert. Deswegen gibt es ja auch eine Abgespeckte Version MQTT-sn. Ich glaube du hast nicht verstanden das dass Transportlayer immer vorhanden sein muss. Fehler auf dieser Ebene sendet der Broker die Will Messages. Das mit der keepalive funktioniert nur wenn der Client mit dem Broker verbunden ist und das Transportlayer keinen Fehler aufweist der zur Unterbrechung der Verbindung führt -> socket close. Disconnect heißt auch disconnect es wird keine Will Messages versendet da die Verbindung ordentlich beendet wurde. Das Problem dabei ist das bei TCP/IP immmer wieder pakete ausgetauscht werden. Legt man den Client schlafen geht die Verbindung verloren da sie in den timeout läuft. Das ganz unabhängig vom MQTT. Das kann auch schon bei sehr langsam und unsichern Verbindungen passieren. Bei UDP wäre das kein Problem aber MQTT schreibt nun mal TCP/IP vor.
:
Bearbeitet durch User
Marco H. schrieb: > Das Problem dabei ist das bei TCP/IP immmer wieder pakete ausgetauscht > werden. Welche denn? Eigentlich nur wenn keepalive aktiviert ist oder in der Applikation ein eigener Watchdog zyklisch die Verbindung kontrolliert. Ansonsten kannst du den Netzwerkstecker ziehen, nach ein paar Tagen wieder einstecken und die Verbindung läuft sofort weiter.
Nö TCP/IP tauscht keine Pakete für einen keep alive aus wenn die Verbindung established ist. Daher versteh ich die Probleme des Threaderstellers nicht. Er is wohl nur zu doof sich mal die gute MQTT Doku von HiveMQ durchzulesen. http://www.hivemq.com/mqtt-essentials/ Also µC schlafen legen mit ner established TCP Verbindung geht. Man msus den MQTT timeout nur hoch genug einstellen und das kann der Client ja. Der MQTT Client sollte auch nichts subscribed haben, sollte der Server über TCP was senden und bekommt kein ACK zurück so schließt er die TCP Verbindung.
Mw E. schrieb: > Nö TCP/IP tauscht keine Pakete für einen keep alive aus wenn die > Verbindung established ist. Und wie wird dann festgestellt das der Gegner lebt? Keepalive sendet zwar keine Daten, aber ein einfaches TCP Paket mit gesetztem ACK Flag das vom Gegner beantwortet werden muss. Beim Deep Sleep ist die Frage was der µC am Leben hält und ob beim Aufwachen die Verbindungsdaten noch da sind. Wenn ja, halte ich das auch für kein Problem den in grösseren Intervallen zu wecken. Und der TCP Stack auf einem PC sollte es schon schaffen einige Tausend oder Zigtausend Verbindugen offen zu halten, soviele Hardwarenodes muss man erstmal haben.
Hallo, Mw E. schrieb: > Also µC schlafen legen mit ner established TCP Verbindung geht. > Man msus den MQTT timeout nur hoch genug einstellen und das kann der > Client ja. Richtig. Meine ESP werden einfach abgeschaltet, teilweise über PowerEnable. KeepAlive sollte natürlich auf einem für die Anwendung sinnvollen Wert stehen, das legt ja der jeweilige Client fest. Ob der Broker seinerseits da was macht, hat mich nie interessiert. Für den ist letztlich nur wichtig, daß sich innerhalb der KeepAlive-Zeit der Client mal gemeldet hat, dann setzt er das TimeOut zurück. Ob das per publish, connect, Brieftaube passiert ist doch von Außen ohnehin nicht wichtig. > Der MQTT Client sollte auch nichts subscribed haben, sollte der Server > über TCP was senden und bekommt kein ACK zurück so schließt er die TCP > Verbindung. Natürlich darf der Client auch Subscriber sein. Je nach gewähltem QoS schickt der Broker bei QoS 0 die Message einemal raus und erledigt oder versucht es mehrfach, wenn QoS 1 oder 2 ist. Ein Publisher erhält sowieso nur eine Quittung bei QoS 1 oder 2, die aber vom Broker, nicht von den Subscribern. Retain fängt ja genau den Fall ab. daß der Subscriber gerade nicht ereichbar ist. Er bekommt diese Message dann, wenn er mal wieder auftaucht. Wenn eine Anwendung 100 Messages/s erfordert und eine ständige Verbindung ist wohl MQTT die falsche Wahl. Gruß aus Berlin Michael
Nun auf der Broker Seite fürt das zu einen Timeout im Socket. Woraus der Broker ein Verbindungsfehler ableitet und die Will Messages sendet. Man kann eine Tcp auch sauber per Disconnect beenden. Ich vermute das in meinen TCP/IP Stack die Verbindung nicht sauber geschlossen wird. Beim Mqtt disconnect ist dies den Broker wurst womit es funktioniert. Ich muss das nochmal prüfen.Im Grunde müßte es funktionieren. Wenn das einfache schlafen legen mit ESP nicht zum senden der Will Messages führt muss auch ein TCP disconnect funktionieren.
Johannes S. schrieb: > Und wie wird dann festgestellt das der Gegner lebt? Garnicht, das ist ein typisches TCP Problem. Das ist das "halb offene Verbindung" Problem. Google mal nach ;) Daher gibts den keep alive auf MQTT Ebene. Der MQTT Client sendet 5min (oder andere Einstellung) lang nix? -> Verbindung oder Client is wohl tot. Michael U. schrieb: > Natürlich darf der Client auch Subscriber sein. Ja türlich, aber bei dem speziellen Fall jetzt eher nicht. Bei dem Fall, dass die TCP Verbindung nicht geschlossen wird und man den Client schlafen legt. Wenn der Client nun nen topic subscribed hat so bekommt er vom Broker ne Nachricht über TCP. DANN! Fällt dem TCP STack auf, dass sich der Client nicht mehr meldet und macht den Socket zu -> MQTT Broker verschickt lastwill messages.
Achso die Verbindungsdaten sind auf jeden Fall verloren. Wenn die Hardware startet ich muss die Verbindungen neu aufbauen. Wenn ein ESP ohne Spannung ist wird dieser auch seinen Speicherinhalt nicht mehr haben. Ein PC kann viele offene Verbindungen verwalten, TCP/IP stacks in Controllern bekommen leicht ein Speicher Problem.
Hallo, Marco H. schrieb: > Nun auf der Broker Seite fürt das zu einen Timeout im Socket. Woraus der > Broker ein Verbindungsfehler ableitet und die Will Messages sendet. nein. Der broker sendet den LastWill wenn bis zum Ablauf der KeepAlive keine Verbindung zum Client mehr zustand kam. Jede Art von Verbindung vom Client seztzt den TimeOut zurück. Wenn z.B. KeepAlive auf 15 Minuten gesetzt ist geht LastWill 15 Minuten nach dem letzten Connect zum Client raus. Wenn der sich innerhalb der 15 Minuten irgendwie meldet, zählen die 15 Minuten wieder ab da. Der Client darf sich nur nicht mit disconnect abmelden, das wäre ein gewünschtes Ende der Verbindung durch den Client. Dann wird KeepAlive ignoriert und es gibt auch kein LastWill. Gruß aus Berlin Michael
Hallo, Marco H. schrieb: > Achso die Verbindungsdaten sind auf jeden Fall verloren. Wenn die > Hardware startet ich muss die Verbindungen neu aufbauen. Wenn ein ESP > ohne Spannung ist wird dieser auch seinen Speicherinhalt nicht mehr > haben. was heißt "Verbindungsdaten" in diesem Fall? Selbstverständlich sind WLAN-Daten, Broker-Adresse usw. im Programm des ESP hinterlegt. Der ESP macht ohnehin beim Neustart einen automatischen Verbindungsversuch zum zuletzt genutzten WLAN. Connect zum Broker usw. incl. Subscribes, KeepAlive, QoS schicke ich beim Aufwecken ohnehin raus. Müßte man nichtmal, der broker merkt sich die letzten Einstellunge, die der Client geschickt hat, wenn der unter seinem Namen wieder auftaucht. TCP/IP, IP usw. sind dem Broker dabei sowieso egal. Für ihn hat der Client nur einen MQTT-Namen. Welcher Speicherinhalt sollte also erhalten bleiben? Das Programm sollte ein µC schon nicht vergessen. ;) Speziell beim ESP ist sogar recht ungünstig, daß er beom WLAN-Connect die Zugangsparameter ins Flash schreibt, egal, ob die verändert sind oder nicht. Ist man erst später drüber gestolpert, kann man auch verhindern. Allerdings ist von meinen ca. 10 ESp8266 hier um mich rum noch keiner daran verstorben. Was bleibt sind also einige Daten, die der RasPi (da läuft Mosquitto drauf) bis zum TCP-Timeout aufhebt, wenn ihm die Verbindung abhanden kommt. So lang ist das TCP-Timeout aber auch nicht, daß deshalb sein Speicher knapp wird... Gruß aus Berlin Michael
Mw E. schrieb: > Garnicht, das ist ein typisches TCP Problem. gut, es gibt 2 keep alive: einmal als socket option auf TCP Level, einmal als MQTT option. Und da es um die Aussage ging das TCP ständig Daten austauscht habe ich das TCP keep alive gemeint. Ohne diese SO_KEEPALIVE ist totale Ruhe bei einer TCP Verbindung wenn keiner auf Applikationsebene was zu sagen hat.
Der Status der TCP/IP Verbindung geht verloren, da der TCP/IP Stack neu initialisiert wird. Wenn dieser sich schlafen legt passiert erst mal nichts, wenn er aufwacht muss die Verbindung neu aufgebaut werden. Dabei landet er am Broker auf eine andere Socketinstance. Dann merkt er das der socket wo der Client ursprünglich verbunden war tot ist. Sendet die Will Messages usw. Wenn man die Verbindung ordentlich schließt sendet der Broker die Will Messages. Das steht auch so im Protokoll -> Verbindungsfehler ... Also immer wenn der Client was dummes feststellt soll er die Verbindung unterbrechen. Aber wir kommen dem Problem immer näher ;) . Nur zu Info ich benutze keinen ESP Client sondern einen µP mit eigenen MQTT Stack. und ich werde mir was anderes einfallen lassen, da vorgesehen war das der Client aufwacht eine Mobilfunkverbindung aufbaut. Sein Mist sendet und Empfängt und sich wieder schlafen legt. Zum empfangen muss er sich sowie so korrekt Abmelden damit die Messages gespeichert werden.
:
Bearbeitet durch User
So also es scheint so das die Sache mit externen TCP/IP Stack -> w5500 wirklich als dumm gelaufen bezeichnet werden kann. Beim SAMW25 verhält sich die Sache anders. Das Wifi kann man schlafen legen und der AP speichert die Pakete zwischen. Er weckt den C1500 auch auf. Ich habe es mit dem Code noch nicht probiert, das kommt später. Jetzt noch eine Praktische Frage. Mein Subscribe Handler baut die Verbindung nur beim retry wieder auf also wenn dieser kein SUBACK erhält versucht er es erneut. Beim Disconnect bekommen die Abonnierten Topics den Anfangsstatus -> nicht versendet. Das Problem sie müssten sonst einen anderen Status bekommen da sonst bei nicht versendeten Topic nach dem disconnect die Verbindung sofort wieder aufgebaut würde. Es war geplant einen refresh einzubauen. Also der Empfangshändler prüft wenn keine Verbindung besteht und wenn Abos vorliegen diese Zeit und baut dann die Verbindung auf. Womit die Subscribe Topics erneut registriert würden. Wenn die Nachrichten gespeichert waren bekommt der Client diese nachgeliefert. Neue Abos würden erst dann mit registriert. Nicht sofort... ich hoffe das ist ok. Die Verbindung wird sofort aufgebaut bei Ping oder Publish nach dem Socket Timeout wird die Verbindung wieder geschlossen.
:
Bearbeitet durch User
Es funktioniert doch mit dem w5500 :) Schlafen legen geht nach wie vor nicht und ich wüsste auch nicht wie das mit dem ESP gehen sollte. Der bootet doch nach dem Aufwachen aus den deep sleep und der RAM Inhalt bleibt nicht erhalten. Das Problem lag im Code an den PHY Link check, der schloss den Socket immer wenn man den Stecker zog. Was unter normalen Bedingungen durch aus akzeptabel ist. Das sorgte eben dafür das die Daten zu der Bestehenden Verbindung nicht passten und der Client unschön getrennt wurde. Bis auf den Empfang von Publish messages funktioniert alles. Danach kann man den Code entschlacken ;)
Meine GÜte ist da wer schwer von Kapie. Less dir nochmal den MQTT Standard durch und wie TCP funktioniert. Es ist MQTT EGAL ob der TCP Verbindungszustand verloren geht wenn man vorher kein discon schickt.
Nö ist es leider nicht, tritt ein Verbindungsproblem auf wird der Client unschön getrennt. Das steht auch so im Standard. Wie schon richtig erwähnt darf keiner von beiden auf die Idee kommen zu senden, sonst stellt einer von beiden fest das die Verbindung nicht vorhanden ist. Die Empfangsfilter funktioniert auch, aus den Abonnierten Topics prüft der Filter die Gültigkeit und startet dann die zugehörige callback Funktion. Ich überlege noch dies in einen Callback Handler zu erledigen, allerdings müsste ich die Daten retten was wieder Speicher kostet. Das ursächliche Problem trat nur auf da ich ein close im TCP/Stack auslöste anstatt die Verbindung richtig zu beenden.
Das hatt ich doch geschrieben... Beim schlafen gehen dürfen keine Subscriptions aktiv sein: Beitrag "Re: MQTT Connect Disconnect" Wer lesen kann ist klar im Vorteil! Also vorm schlafen legen desubscriben, wenn man denn unbedingt topics subscribed haben muss.
oder sauberer Disconnect und die Messages mit Retain senden. Die Performance des Codes denke ich ist auch ganz ok 100 Messages mit Qos 1 inkl. sie wieder auf den gleichen Client zu empfangen mit Qos 1 laufen in ca 1,5sec durch. na mal schauen ein paar Bugs muss ich noch beheben ;)
Eine schwierige Geburt der MQTT stack auf einen ESP32 ... Noch mit ein paar ecken ? Sagt mal gibt es einen event Handler für den lwip wenn daten angekommen sind ? oder muss ich jedes mal mal per resv(); die Rückgabe prüfen ? Für etwas was in einer Task läuft relativ blöd .
Für alle Negativ bewerter der Code läuft jetzt stabil auf dem ESP32. Ein schöner Bug im Teil der für eine unique PacketID sorgte griff auch in die Liste wenn sie leer war. Deswegen zog der Kernel immer die Reißleine beim reconnect, da sie dann meist leer ist ;) Der Code ist jetzt auch etwas RTOS like.. Ich habe jetzt 6 Clients schon tage am laufen... Was man schon sagen kann das der ESP32 deutlich mehr Strom braucht als der Winc1500. Der Preis lockt schon das Projekt doch auf den ESP laufen zu lassen ;)
Es gibt Neuigkeit :) - URL,DNS, Websocket Support Hat etwas gedauert da diese Fähigkeiten diverse Nebenbaustellen aufmachten. SHA1,base64,DNS,URI parser, http parser usw. bis auf dem Random Generator alles in Software. Läuft momentan auf einen Arduino DUE, da sich dieser einfacher debuggen lässt als der ESP. Auf diesen kann man dann die Hardware für SHA1 und TLS benutzen. TLS geht auf dem sam3x bzw. wiznet nicht. Die performance liegt beim Websocketconnect und QOS2 bei ca 260 Messages in der Sekunde. Der Websocketsupport wurde integriert da alles weitere den Code so aufgeblasen hätten und vieles doppelt verarbeitet würde. Viele Sachen in der URI kann man ja für DNS etc gebrauchen. Der HTTP parser wurde auf das minimale programmiert und zieht sich das aus der response was benötigt wird. Aus der URL wird auch abgeleitet welchen Connect es bedarf -> ws://test.de -> websocket auf standard port oder ws://test.de:8000 , path geht auch :)
:
Bearbeitet durch User
Um die Sache etwas aufzuheitern komme ich noch mal auf die Ursprungsfrage des Thread zurück. Das Geheimnis verbirgt sich hinten dem "Clean Session" Flag vom Connect. Setzt man dieses nicht speichert der Broker alle Messages QOS1,QOS2 zwischen, optional auch QOS0. Die Anzahl ist abhängig vom inflight Level im Broker. Ausschlaggebend ist die Client ID, deswegen sollte man auch nicht diese per ramdom erzeugen. Da sonst der Broker den Client nicht mehr zuordnen kann und immer wieder neue Session erzeugt. Alle Abonnierten Themen bleiben im Broker erhalten ohne das "Clean Session" Flag. Ist der client nicht bekannt erzeugt der Broker eine neue Session. Ob die Session bekannt ist kann man am return Code vom Connect ACK ableiten. Dann muss man ggf. die Themen neu abonnieren. Man kann also das Gerät schlafen legen ohne etwas zu verpassen. Man muss nur dafür sorgen das es ab und zu mal wieder aufwacht. Der Stack läuft jetzt auch allen 3 Plattformen. Sam3x,SAMW25,ESP32. Auch habe ich das Problem mit der 6 Tage Laufzeit beim ES32 vermutlich gefunden. Das Problem tritt auf wenn das Wifi disconnected wird oder auch abschmiert. Die Anwendertask prüft dann einen timeout der einen connection Thread startet der den Verbindungsaufbau anschiebt. Der Teil anhält so wenige Anweisungen das dies wie eine for schleife ohne Bedingungen wirkt. Der Code in der Schleife ist zu gering und die Task kann nicht mehr durch das RTOS unterbrochen werden. Das dumme daran ist das ich einen Sekunden Tick durch einen Softwaretimer habe der nun auch nicht mehr bedient wird. So kommt das ganze nie mehr aus der schleife heraus. (nein es ist keine schleife ;) nach der Prüfung wird die Funktion verlassen, wirkt aber so da nur wenige Anweisungen ausgeführt werden müssen) Das Fix jetzt kommts, ist ein vTaskdelay von 100ms also alle 100ms wird geschaut ob der Timeout abgelaufen ist. Die Task wird schlafen geschickt und der Watchdoog,Softwaretimer wird bedient. Das klingt komisch, ich suche auch die stelle an der ich lachen muss. Ich müsste mal nachschauen was der Compiler an der entsprechende stelle gebaut hat ;). Das ganze ist aber erklärbar. Die Last geht an der Stelle von der Anwendertask auf 100%, das schlafen legen ist also nicht der falsche weg. Oder warten auf ein Event. Das würde aber zu sehr in das Codekonzept eingreifen. Es wäre nicht mehr auf nicht RTOS Plattformen portierbar.
:
Bearbeitet durch User
So das Projekt ist eine ganze Ecke weiter :) Jetzt richtig RTOS like mit Evenhandler und getrennten Task. Überarbeiten Socket Funktionen usw. Anbei eine Verbindung zum AWS per TLS und MQTT. Allerdings ist hier der MQTT Support etwas eingeschränkt. - Amazon unterstützt kein QOS2, bei Messages mit QOS 2 wird kein ACK gesendet - beim Abonnieren mit QOS2 wird die Verbindung getrennt - keine persistenten Verbindungen!, das cleanSession Flag ist unbedingt zu setzen und es betrifft auch WILL Messages, WILL QOS die nicht gesetzt werden dürfen. Bei nicht unterstützen Flags wird die Verbindung beendet. Auf der Gegenseite wird ein AWS Account, Zertifikate für TLS und eine Policies benötigt. Sonst ist kein Verbindungsaufbau möglich.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.