Im Folgenden beschreibe ich einige Frameworks, die einigen Bekanntheitsgrad erlangt haben und Merkmale aufweisen, die sie für unser Ziel geeignet machen. Ich werde erläutern, warum sie erfunden wurden und inwiefern sie sich eignen. Die Aufzählung beginnt mit Jini, erstreckt sich über Node.js und Twisted und endet mit MQTT, das sich nach meinem Dafürhalten zum De-facto-Standard für die geschlossenen Implementierungen entwickeln wird.
Jini (jetzt Apache River)
Venerable Jini [12], [13] wurde Ende der 90er Jahre von Sun entwickelt und wird heute als Apache River-Projekt weitergeführt. Es basiert auf Java. Es wurde entwickelt, um es modularen Diensten zu ermöglichen, sich über ein Netzwerk miteinander zu verbinden und auf diesem Weg eine sogenannte Service-Objekt-orientierte Architektur zu etablieren. Interessant an Jini war u. a. die Fähigkeit, dass sich Netzwerkeinheiten (z. B. Dienste) selbst erkennen können. Dies erfolgt über einen zentralen Broker (ein Lookup-Service), den alle Clients kontaktieren, um Informationen über die anderen einzuholen. Einmal erkannt, können die Dienste miteinander interagieren. Es heißt, dass sich der Lookup-Service nicht gut auf sehr große Systeme skalieren lässt. Und beim IoT geht es um potenziell riesige Systeme.
Bei Jini gab es drei übergeordnete Ziele: Erstens Clients sollten nicht wissen müssen, wo sich ein bestimmter Dienst befindet, und zweitens Clients sollten nicht fehlschlagen, wenn der Dienst nicht verfügbar ist oder während der Ausführung seine Verfügbarkeit einbüßt, und (3) Clients und Dienste sollten proaktiv sein, um Fehlerzustände zu erkennen. Das sind auch für unseren Standard angemessene Ziele.
Da Jini auf Java basiert, gibt es eine gewisse Verbindung zu eingebetteten Geräten, weil Java ja ursprünglich als Plattform für kleine, eingebettete Systeme in elektronischen Geräten wie Set-Top-Boxen gedacht war. So weit, so gut, aber Java ist die Sprache von IT-Abteilungen. Es ist heute keine Plattform für kleine eingebettete Systeme mehr, sofern es sich dabei nicht um Einplatinencomputer (SBC) wie den BeagleBone Black oder den Raspberry Pi handelt. Dennoch ist die Objekterkennung ein nettes Feature für unsere Spezifikation. Und auch das Konzept eines zentralisierten Brokers als optionale Komponente ist eine praktische Sache. Wie bereits erwähnt, handelt es sich bei den heute existierenden geschlossenen Systemen im Wesentlichen um zentralisierte Broker. Ich sehe darin einen gewissen Wert, aber nur als Option.
Node.js14
Node.js wurde 2009 entwickelt, um Webservern die Möglichkeit zu geben, in Eigenregie eine Verbindung zu den Clients herzustellen. Klingt gut: Unsere eingebetteten IoT-Geräte kann man sich vereinfacht als kleine Webserver vorstellen. Also könnte das zu unserem Szenario passen.
Auf der node.js-Website heißt es: »Node.js nutzt ein ereignisgesteuertes, nicht blockierendes I/O-Modell, wird dadurch schlank und effizient und eignet sich perfekt für datenintensive Echtzeitanwendungen, die auf verteilten Geräten laufen.« Das klingt nach der perfekten Plattform. Allerdings basiert node.js auf der JavaScript-Laufzeitumgebung von Chrome, und »Echtzeit« bedeutet hier websitzungsbasiert – und das ist etwas völlig anderes als Echtzeit in unserem Embedded-Kontext. Nehmen Sie beispielsweise die Datenrate, die für ein IoT-Gerät erforderlich ist, das Zyklen durchläuft, die eine Verpackungsmaschine ausführt. Diese Maschinen verpacken Waren mit einem Durchsatz von Tausenden Stück pro Minute. Node.js wurde einfach nicht für die Echtzeit-Performance entwickelt, wie sie die meisten IoT-Geräte benötigen.
Zudem würde das IoT-Gerät bei nicht modifiziertem Einsatz mindestens eine JavaScript-Engine benötigen. Nun sind JavaScript-Engines ja normalerweise in Webserver wie Apache integriert; es gibt zwar noch weitere Möglichkeiten wie V8 [15] und TraceMonkey [16], aber keine davon ist für ihre Geschwindigkeit bekannt. Das bedeutet, dass node.js wahrscheinlich zu komplex für den Einsatz in IoT-Geräten ist. Diese Plattform eignet sich für Einplatinencomputer oder besser noch komplette PCs. Kurzum: node.js ist meines Erachtens keine gute Plattform für unseren Standard.
Twisted
Twisted [13] ist in Python geschrieben und wurde für die Entwicklung von Internetanwendungen, insbesondere von Spielen, entwickelt. Es ist ein ereignisgesteuertes Netzwerk-Programmier-Framework. Entwickler schreiben Callback-Routinen, die vom Framework aufgerufen werden. Twisted sollte Spieleentwicklern damals die Möglichkeit geben, internetbasierte Kommunikation in ihre Spiele einzubetten. TCP- und UDP-Dienste sowie ein Unix-Socket-Interfacing-Modell bilden den Kern dieses Frameworks.
Ein Vorteil von Twisted mit seiner Python-Basis ist, dass die zugrunde liegende Engine, die Python-Engine, unter anderem in C geschrieben ist. Das ist ein großer Vorteil im Hinblick auf die Lauffähigkeit auf eingebetteten Geräten, weil fast alle eingebetteten Geräte für C entwickelt werden. CPython [17] ist die Python-Haupt-Engine, es gibt aber auch Engines wie PyMite18, die auf 8-Bit-Geräten mit nur 64 KB nichtflüchtigem Speicher und 4 KB RAM laufen. Das heißt aber nicht, dass ein IoT-Gerät zwangsläufig ein 8-Bit-Gerät sein sollte. Ich erwähne das nur, um zu verdeutlichen, wie kompakt eine Python-Engine sein kann. Aufgrund der erwähnten Lasten durch TCP/IP wird von IoT-Geräten erwartet, dass sie 32-Bit-Kerne einbetten. Twisted scheint ein würdiger Rahmen für unseren Standard zu sein.
Python kann auch in Produkte eingebettet werden, um Endanwendern eine integrierte Programmierschnittstelle zur Verfügung zu stellen [19]. Bei Twisted sieht das sogar noch besser aus. Programmierbare IoT-Geräte können jetzt von Endanwendern in Python programmiert werden. Sehr schön!
Die von Twisted benötigten Callback-Routinen heißen »deferreds«. Sie laufen asynchron zur sonstigen Verarbeitung. Das erfordert eine andere Denkweise, damit die Echtzeitverarbeitung funktioniert. Normalerweise werden Aufgaben mit hoher Priorität in einer Interrupt-Service-Routine platziert. Asynchrone Callbacks erfordern jedoch alternative Ansätze zur Unterbrechung von Routinen, z. B. semaphorenbasiertes Gating. Das Endergebnis kann nur eine Fast-Echtzeit-Performance sein – ein Zustand, in dem gelegentliche Verluste von Echtzeit-Ereignissen toleriert werden.
Twisted ist so konzipiert, dass es an einem oder beiden Enden einer Client-Server-Verbindung implementiert werden kann. Da der Mechanismus beliebige Informationen über die TCP/IP-Suite von Diensten senden kann, bleibt er ein guter Kandidat.
Twisted umfasst jedoch keine Klassentypdefinitionen im USB-Stil. Dadurch ist Twisted für jede Ad-hoc-Anwendung bzw. jedes Produkt, das über eine TCP/IP-basierte Schnittstelle verfügt, einfach einzusetzen. Für die Einbindung eines Gerätes in eine Anwendung wird jedoch benutzerdefinierter Code benötigt. Twisted benötigt eine Gerätetypspezifikation wie USB On-The-Go, damit bekannte Geräte ohne Neuentwicklung in die Anwendung eingebunden werden können. Diese Spezifikation muss an einem der Enden oder an beiden Enden einer Verbindung vorliegen.
OASIS MQTT
MQTT (Message Queue Telemetry Transport) [20] ist ein schlankes Publish/Subscribe-Nachrichtenprotokoll. Ursprünglich entwickelt von IBM und Arcom wurde es 2014 zu einem offenen Standard von OASIS. OASIS sieht seine Aufgabe darin, die Entwicklung, Konvergenz und Durchsetzung offener Standards für die globale Datenkommunikation voranzutreiben.
MQTT wird als äußerst einfach und schlank beschrieben und ist für Geräte mit Beschränkungen sowie Netzwerke mit geringer Bandbreite, hoher Latenz oder schwankender Zuverlässigkeit ausgelegt. Ziel ist es, die Netzwerkbandbreite und den Ressourcenbedarf der Geräte ohne Beeinträchtigung der Zuverlässigkeit zu minimieren und die Zustellung der Nachrichten zu garantieren. MQTT wurde als ideal für das IoT angepriesen, und es hat eine weite Verbreitung.
Als Protokoll muss es implementiert werden, um zum vollständigen Framework zu werden. Eine solche Implementierung ist das Eclipse-Paho-Projekt. Es unterstützt MQTT in einer Vielzahl von Sprachen, darunter C/C++, Java, JavaScript und Python [21]. Die meisten Implementierungen sind für die Client-Seite vorgesehen, aber auch serverseitige Implementierungen sind verfügbar.
Der Server wird in MQTT als »Message Broker« bezeichnet. Im Gegensatz zu Twisted, bei dem Endgeräte direkt miteinander kommunizieren können, muss dies bei MQTT in der Regel über diesen Message Broker erfolgen.
Eine Python-Implementierung eines MQTT-Brokers ist beispielsweise Mosquitto; mit Apache ActiveMQ wäre eine weitere zu nennen. ActiveMQ ist eine Java-Implementierung mit Anbindungen an viele weitere Sprachen. Mit RabbitMQ und ZeroMQ gibt es noch weitere Message Broker. Darüber hinaus gibt es noch Broker, die verschiedene andere IT-Protokolle unterstützen.
Wie bereits erwähnt, greifen viele proprietäre IoT-Lösungen für das Messaging auf MQTT zurück. Das Problem dabei ist, dass kein Standard regelt, welche Daten von welchen IoT-Geräten kommuniziert werden müssen. Die existierenden MQTT-Implementierungen sind nur mit sich selbst kompatibel. Das Protokoll ermöglicht zwar die Kommunikation von Nachrichten, aber nur die IoT-Geräte, die für diese Nachrichten konzipiert wurden, verstehen, was sie bedeuten. Für jedes andere Gerät, das die Informationen eigentlich nutzen könnte, sind die Nachrichten nur Kauderwelsch. Dasselbe gilt für Twisted. Perfekt wäre es, Twisted mit MQTT als Protokoll zu verwenden. Dann muss es aber für jede Art von IoT-Funktion einen Nachrichteninhaltsstandard geben.