Python WebSockets mit Tornado auf dem Raspberry Pi: Schritt-für-Schritt-Anleitung
In diesem Beitrag zeige ich, wie man mit Python und dem Tornado-Framework einen WebSocket-Server zur bidirektionalen Kommunikation auf einem Raspberry Pi aufbaut.
Das Tornado-Framework verwende ich unter anderem auch in den folgenden Beiträgen:
- Schrittmotor am Raspberry Pi über Webinterface steuern
- Mobile WebApp für die Temperaturmessung am Raspberry Pi
- Web zu UART Terminalprogramm auf dem Raspberry Pi
In Aktion zur Steuerung eines NIBOBee Roboters kannst du dir auch mein Video mit dem Titel NIBOBee Roboter mit Raspberry Pi auf YouTube ansehen.
Bevor wir uns näher mit dem Tornado Framework und dessen Konfiguration beschäftigen, möchte ich versuchen, dir das Grundkonzept von WebSockets zu erklären.
Was sind WebSockets?
WebSockets sind eine Technologie, die eine beidseitige, fortlaufende Verbindung zwischen einem Client (z. B. einem Webbrowser) und einem Server ermöglicht. Im herkömmlichen HTTP muss der Client jedes Mal die Kommunikation in Gang setzen und der Server antworten. Mit WebSockets können jedoch Server und Client jederzeit Daten hin- und her senden, ohne dass eine neue Verbindung aufgebaut werden muss. Dies ist gut für Programme geeignet, die sofortige Daten benötigen, wie Online-Spiele, Chat-Programme oder Börsenticker.
Wenn du etwas tiefer in das Thema einsteigen möchtest, kann ich dir das Buch “WebSockets: Moderne HTML5-Echtzeitanwendungen entwickeln” nur empfehlen.
Tornado und dessen Rolle in der Welt der WebSockets
Tornado ist eine leistungsstarke Python-Bibliothek, mit der du asynchrone Webserver erstellen kannst. Das bedeutet, dass es mehrere Anfragen gleichzeitig bearbeiten kann, ohne blockiert zu werden. Ein großer Vorteil von Tornado ist dabei seine eingebaute Unterstützung für WebSockets. Weitere Informationen findest du unter https://www.tornadoweb.org/.
Vorteile von WebSockets
Die Vorteile im Überblick:
- Echtzeitkommunikation
- Effizienz
- Asynchronität
Einrichtung des Raspberry Pi
Schritt 1: Raspberry Pi vorbereiten
Stelle sicher, dass dein Raspberry Pi auf dem neuesten Stand ist. Gebe hierzu im Terminal folgende Befehle ein:
1 |
sudo apt update && sudo apt upgrade |
Schritt 2: Tornado installieren
Anmerkung vom 18.10.2023
Wie in meinem Beitrag “Ein Blick auf das Raspberry Pi OS “Bookworm”” zur neuen Version des Raspberry Pi OS Bookworm (Stand 10.10.2023) angemerkt, funktioniert die Einbindung von Python-Bibliotheken nicht mehr wie gewohnt und führt zu einem Fehler. Daher schon jetzt der Hinweis: Solltest du eine neuere Version des Raspberry Pi OS als Bullseye (Stand 03.05.2023) verwenden, musst du die Tornado-Bibliotheken anders einbinden. Der Befehl lautet:
1 |
sudo apt install python3-tornado |
Installiere das Tornado-Framework über pip mit dem Befehl:
1 |
sudo pip3 install tornado |
Solltest du das Paketinstallationsprogramm PIP für Python bislang nicht installiert haben, kannst du dies mit folgendem Befehl nachholen:
1 |
sudo apt-get install python3-pip |
Eine Übersicht über wichtige und häufig verwendete Befehle stelle ich dir auf einem kleinen Spickzettel für Raspberry Pi OS Befehle zur Verfügung.
Schritt 3: Einfacher WebSocket-Server erstellen
Erstelle eine einfache Python-Datei, zum Beispiel websocket_server.py, und füge folgenden Code ein:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import tornado.ioloop import tornado.web import tornado.websocket class WebSocketHandler(tornado.websocket.WebSocketHandler): def check_origin(self, origin): return True def open(self): print("WebSocket geöffnet") def on_message(self, message): self.write_message("Du hast gesagt: " + message) print ("Eingabe des Users: " + message) def on_close(self): print("WebSocket geschlossen") app = tornado.web.Application([ (r"/websocket", WebSocketHandler), ]) if __name__ == "__main__": app.listen(9090) tornado.ioloop.IOLoop.current().start() |
Schritt 4: Server starten
Starte den WebSocket-Server mit dem Befehl:
1 |
python3 websocket_server.py |
Der WebSocket-Server läuft jetzt auf Port 9090 deines Raspberry Pi.
Schritt 5: Einfache HTML-Datei mit entsprechendem JavaScript
Der bereitgestellte Code erstellt einen einfachen WebSocket-Server mit Tornado. Um mit dem Server zu arbeiten, brauchst du eine HTML-Datei mit entsprechendem JavaScript, um eine Verbindung herzustellen und Nachrichten zu senden und zu empfangen.
Hier findest du ein einfaches Beispiel für eine solche HTML-Datei. Denke daran, dass diese im entsprechenden Ordner deines Webservers abgespeichert ist, um auch von externen Geräten erreichbar zu sein.
Die Einrichtung eines Webservers habe ich in meinem Beitrag “Apache Webserver, PHP, SQL Datenbank und FTP Zugang auf dem Raspberry Pi einrichten” beschrieben.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<!DOCTYPE html> <html lang="de"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>WebSocket Test mit Tornado</title> <script> document.addEventListener("DOMContentLoaded", function() { var ws = new WebSocket("ws://localhost:9090/websocket"); ws.onopen = function(event) { console.log("Verbindung hergestellt"); }; ws.onmessage = function(event) { var msgDiv = document.getElementById("messages"); msgDiv.innerHTML += event.data + "<br/>"; }; document.getElementById("sendButton").addEventListener("click", function() { var input = document.getElementById("messageInput").value; ws.send(input); }); }); </script> </head> <body> <h2>WebSocket Test mit Tornado</h2> <input type="text" id="messageInput" placeholder="Nachricht eingeben"> <button id="sendButton">Senden</button> <div id="messages"></div> </body> </html> |
Wenn du diese Webseite in deinem Browser öffnest und eine Nachricht über das Eingabefeld sendest, wird der Tornado-WebSocket-Server sie empfangen und eine Antwort zurückschicken. Die Antwort, welche “Du hast gesagt: ” gefolgt von deiner Nachricht zeigt, wird dann im messages-Div der Webseite angezeigt.
Die folgende Slideshow zeigt die 3 Phasen einer Verbindung zwischen dem Client (Browser) und dem WebSocket Server (Python Skript).
Fazit
Die relativ einfache Einrichtung eines WebSocket-Servers mit Python und Tornado auf einem Raspberry Pi bietet unglaublich spannende Möglichkeiten, insbesondere im Bereich des Internets der Dinge (IoT). Mit WebSockets kannst du eine schnelle und reaktionsfähige Kommunikation zwischen deinem Raspberry Pi und anderen Geräten oder Clients aufbauen.
Bereitgestellte Dateien und Links
Wenn du dir das Abtippen oder Kopieren des Codes sparen möchtest, steht dir der Code in einer ZIP-Datei zum Download bereit.
Gib im Terminal folgenden Befehl ein, dieser lädt die ZIP-Datei auf deinen Raspberry Pi herunter.
1 |
wget https://webnist.de/downloads/websocket.zip |
Hallo Herr Raab
können Sie mir sagen wo der Ordner des Webservers liegt in den ich die HTML datei abspeichern muss? Ich bekomme den befehl Websocket geöffnet nicht wenn ich die Webseite im Browser öffne, bzw. wenn ich das Programm ausführe.
Ich bin in der Ordnerstruktur mit dem Raspberry noch nicht so bewandert.
Vielen dank schon mal für ihre Hilfe.
VG
Hallo Herr Luthner,
die html-Datei gehört in das vom Webserver bereitgestellte Verzeichnis /var/www/html/ gespeichert und über den Webserver (auf dem Raspberry Pi über localhost oder per IP des Raspberry aufgerufen).
Die Installation des Apache Webserver habe ich hier beschrieben: https://webnist.de/webserver-php-sql-datenbank-und-ftp-zugang-einrichten/
Viele Grüße
Wolfgang
Kleiner Hinweis, alle Kommentare werden moderiert.
Dies bedeutet, der Kommentar wird vor der Veröffentlichung durchgelesen und von mir geprüft. Auch behalte ich mir vor, jeden Kommentar zu löschen, der nicht direkt auf das Thema abzielt oder nur den Zweck hat, Leser oder Autoren herabzuwürdigen.