Demo zur gemeinsamen Nutzung von CoreMQTT-Agenten - FreeRTOS

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Demo zur gemeinsamen Nutzung von CoreMQTT-Agenten

Wichtig

Diese Demo wird im Amazon-FreeRTOS-Repository gehostet, das veraltet ist. Wir empfehlen, dass Sie hier beginnen, wenn Sie ein neues Projekt erstellen. Wenn Sie bereits ein vorhandenes FreeRTOS-Projekt haben, das auf dem inzwischen veralteten Amazon-FreeRTOS-Repository basiert, finden Sie weitere Informationen unter. Leitfaden zur Migration des Amazon-FreerTOS Github-Repositorys

Einführung

Das Demo-Projekt CoreMQTT Connection Sharing zeigt Ihnen, wie Sie mit einer Multithread-Anwendung eine Verbindung zum AWS MQTT-Broker mithilfe von TLS mit gegenseitiger Authentifizierung zwischen dem Client und dem Server herstellen können. Diese Demo verwendet eine MbedTLS-basierte Transportschnittstellenimplementierung, um eine server- und clientauthentifizierte TLS-Verbindung herzustellen, und demonstriert den Subscribe-Publish-Workflow von MQTT auf QoS 1-Ebene. Die Demo abonniert einen Themenfilter, veröffentlicht Themen, die dem Filter entsprechen, und wartet dann auf den Empfang dieser Nachrichten vom Server auf QoS 1-Ebene. Dieser Zyklus, bei dem die Veröffentlichung auf dem Broker und die gleiche Nachricht vom Broker zurückgesendet wird, wird für jede erstellte Aufgabe mehrmals wiederholt. Nachrichten in dieser Demo werden mit QoS 1 gesendet, was mindestens eine Lieferung gemäß der MQTT-Spezifikation garantiert.

Anmerkung

Folgen Sie den Schritten unter, um die FreeRTOS-Demos einzurichten und auszuführen. Erste Schritte mit FreeRTOS

Diese Demo verwendet eine Thread-sichere Warteschlange, in der Befehle für die Interaktion mit der MQTT-API gespeichert werden. In dieser Demo gibt es zwei Aufgaben, die Sie beachten sollten.

  • Eine (Haupt-) Aufgabe des MQTT-Agenten verarbeitet die Befehle aus der Befehlswarteschlange, während andere Aufgaben sie in die Warteschlange einreihen. Diese Aufgabe tritt in eine Schleife ein, in der sie Befehle aus der Befehlswarteschlange verarbeitet. Wenn ein Terminierungsbefehl eingeht, wird diese Aufgabe aus der Schleife ausbrechen.

  • Eine Demo-Subpub-Aufgabe erstellt ein Abonnement für ein MQTT-Thema, erstellt dann Veröffentlichungsvorgänge und schiebt sie in die Befehlswarteschlange. Diese Veröffentlichungsvorgänge werden dann von der MQTT-Agent-Aufgabe ausgeführt. Die Demo-Subpub-Aufgabe wartet, bis die Veröffentlichung abgeschlossen ist, was durch die Ausführung des Callbacks zur Befehlsvervollständigung angezeigt wird, und gibt dann eine kurze Verzögerung ein, bevor sie mit der nächsten Veröffentlichung beginnt. Diese Aufgabe zeigt Beispiele dafür, wie Anwendungsaufgaben die CoreMQTT-Agenten-API verwenden würden.

Für eingehende Veröffentlichungsnachrichten ruft der CoreMQTT-Agent eine einzige Callback-Funktion auf. Diese Demo beinhaltet auch einen Abonnement-Manager, der es Aufgaben ermöglicht, einen Callback anzugeben, der für eingehende Veröffentlichungsnachrichten zu Themen aufgerufen werden soll, die sie abonniert haben. Der eingehende Veröffentlichungsrückruf des Agenten in dieser Demo ruft den Abonnementmanager auf, um Veröffentlichungen für alle Aufgaben, für die ein Abonnement registriert wurde, aufzufächern.

In dieser Demo wird eine TLS-Verbindung mit gegenseitiger Authentifizierung für die Verbindung verwendet. AWS Wenn das Netzwerk während der Demo unerwartet unterbrochen wird, versucht der Client, mithilfe der exponentiellen Backoff-Logik erneut eine Verbindung herzustellen. Wenn der Client die Verbindung erfolgreich wiederherstellt, der Broker die vorherige Sitzung jedoch nicht fortsetzen kann, abonniert der Client dieselben Themen wie in der vorherigen Sitzung erneut.

Single-Threading oder Multithreading-fähig

Es gibt zwei CoreMQTT-Nutzungsmodelle: Singlethread und Multithread (Multitasking). Das Single-Thread-Modell verwendet die CoreMQTT-Bibliothek ausschließlich von einem Thread aus und erfordert, dass Sie wiederholte explizite Aufrufe in der MQTT-Bibliothek tätigen. Multithread-Anwendungsfälle können stattdessen das MQTT-Protokoll im Hintergrund innerhalb einer Agenten- (oder Daemon-) Aufgabe ausführen, wie in der hier dokumentierten Demo gezeigt. Wenn Sie das MQTT-Protokoll in einer Agententask ausführen, müssen Sie keinen MQTT-Status explizit verwalten oder die API-Funktion aufrufen. MQTT_ProcessLoop Wenn Sie eine Agententask verwenden, können sich außerdem mehrere Anwendungsaufgaben eine einzige MQTT-Verbindung teilen, ohne dass Synchronisationsprimitive wie Mutexe erforderlich sind.

Quellcode

Die Demo-Quelldateien sind benannt mqtt_agent_task.c simple_sub_pub_demo.c und befinden sich im freertos/demos/coreMQTT_Agent/ Verzeichnis und auf der Website. GitHub

Funktionalität

Diese Demo erstellt mindestens zwei Aufgaben: eine primäre, die Anfragen für MQTT-API-Aufrufe verarbeitet, und eine konfigurierbare Anzahl von Unteraufgaben, die diese Anfragen erstellen. In dieser Demo erstellt die Hauptaufgabe die Unteraufgaben, ruft die Verarbeitungsschleife auf und bereinigt sie anschließend. Die Hauptaufgabe erstellt eine einzelne MQTT-Verbindung zum Broker, die von den Unteraufgaben gemeinsam genutzt wird. Die Unteraufgaben erstellen ein MQTT-Abonnement beim Broker und veröffentlichen dann Nachrichten an diesen. Jede Unteraufgabe verwendet ein eigenes Thema für ihre Veröffentlichungen.

Hauptaufgabe

Die Hauptaufgabe der Anwendung, RunCoreMQTTAgentDemo, richtet eine MQTT-Sitzung ein, erstellt die Unteraufgaben und führt die Verarbeitungsschleife MQTTAgent_ aus, CommandLoop bis ein Abschlussbefehl empfangen wird. Wenn das Netzwerk unerwartet unterbrochen wird, stellt die Demo im Hintergrund wieder eine Verbindung zum Broker her und stellt die Abonnements beim Broker wieder her. Nachdem die Verarbeitungsschleife beendet wurde, wird die Verbindung zum Broker getrennt.

Befehle

Wenn Sie eine CoreMQTT-Agenten-API aufrufen, erstellt sie einen Befehl, der an die Warteschlange der Agentenaufgabe gesendet wird, in der sie verarbeitet wird. MQTTAgent_CommandLoop() Zum Zeitpunkt der Erstellung des Befehls können optionale Callback- und Kontextparameter für die Fertigstellung übergeben werden. Sobald der entsprechende Befehl abgeschlossen ist, wird der Abschluss-Callback mit dem übergebenen Kontext und allen Rückgabewerten, die als Ergebnis des Befehls erstellt wurden, aufgerufen. Die Signatur für den Abschluss-Callback lautet wie folgt:

typedef void (* MQTTAgentCommandCallback_t )( void * pCmdCallbackContext, MQTTAgentReturnInfo_t * pReturnInfo );

Der Kontext der Befehlsvervollständigung ist benutzerdefiniert; für diese Demo lautet er: struct. MQTTAgent CommandContext

Befehle gelten als abgeschlossen, wenn:

  • Abonniert, kündigt und veröffentlicht mit QoS > 0: Sobald das entsprechende Bestätigungspaket empfangen wurde.

  • Alle anderen Operationen: Sobald die entsprechende CoreMQTT-API aufgerufen wurde.

Alle vom Befehl verwendeten Strukturen, einschließlich Veröffentlichungsinformationen, Abonnementinformationen und Abschlusskontexten, müssen im Gültigkeitsbereich bleiben, bis der Befehl abgeschlossen ist. Eine aufrufende Aufgabe darf keine der Strukturen eines Befehls wiederverwenden, bevor der Abschluss-Callback aufgerufen wurde. Beachten Sie, dass der Completion-Callback, da er vom MQTT-Agenten aufgerufen wird, im Thread-Kontext der Agentenaufgabe ausgeführt wird, nicht mit der Aufgabe, die den Befehl erstellt hat. Prozessübergreifende Kommunikationsmechanismen, wie Aufgabenbenachrichtigungen oder Warteschlangen, können verwendet werden, um der aufrufenden Aufgabe zu signalisieren, dass der Befehl abgeschlossen ist.

Die Befehlsschleife ausführen

Befehle werden kontinuierlich in verarbeitetMQTTAgent_CommandLoop(). Wenn es keine Befehle gibt, die verarbeitet werden müssen, wartet die Schleife, bis maximal einer MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME zur Warteschlange hinzugefügt wird, und wenn kein Befehl hinzugefügt wird, wird eine einzelne Iteration von MQTT_ProcessLoop() ausgeführt. Dadurch wird sichergestellt, dass MQTT Keep-Alive verwaltet wird und dass alle eingehenden Veröffentlichungen auch dann empfangen werden, wenn sich keine Befehle in der Warteschlange befinden.

Die Befehlsschleifenfunktion wird aus den folgenden Gründen zurückkehren:

  • Ein Befehl gibt außerdem einen beliebigen Statuscode zurückMQTTSuccess. Der Fehlerstatus wird von der Befehlsschleife zurückgegeben, sodass Sie entscheiden können, wie Sie damit umgehen möchten. In dieser Demo wird die TCP-Verbindung wieder hergestellt und es wird versucht, die Verbindung wiederherzustellen. Wenn ein Fehler auftritt, kann eine Wiederverbindung im Hintergrund erfolgen, ohne dass andere Aufgaben, die MQTT verwenden, eingreifen müssen.

  • Ein Befehl zum Trennen der Verbindung (vonMQTTAgent_Disconnect) wird verarbeitet. Die Befehlsschleife wird beendet, sodass die TCP-Verbindung getrennt werden kann.

  • Ein Terminierungsbefehl (vonMQTTAgent_Terminate) wird verarbeitet. Dieser Befehl markiert außerdem jeden Befehl, der sich noch in der Warteschlange befindet oder auf ein Bestätigungspaket wartet, als Fehler mit dem Rückgabecode. MQTTRecvFailed

Abonnement-Manager

Da die Demo mehrere Themen verwendet, ist ein Abonnement-Manager eine bequeme Möglichkeit, abonnierte Themen mit eindeutigen Rückrufen oder Aufgaben zu verknüpfen. Der Abonnementmanager in dieser Demo ist Single-Thread-fähig und sollte daher nicht von mehreren Aufgaben gleichzeitig verwendet werden. In dieser Demo werden Abonnement-Manager-Funktionen nur von Callback-Funktionen aufgerufen, die an den MQTT-Agenten übergeben werden, und nur im Thread-Kontext der Agentenaufgabe ausgeführt.

Einfache Aufgabe zum Abonnieren und Veröffentlichen

Jede Instanz von prvSimpleSubscribePublishTaskerstellt ein Abonnement für ein MQTT-Thema und erstellt Veröffentlichungsvorgänge für dieses Thema. Um mehrere Veröffentlichungstypen zu demonstrieren, verwenden gerade nummerierte Aufgaben QoS 0 (die abgeschlossen sind, sobald das Veröffentlichungspaket gesendet wurde) und ungerade Aufgaben verwenden QoS 1 (die nach Erhalt eines PUBACK-Pakets abgeschlossen sind).