Kapitel 6 · Übung
Die Bibliothek websockets, ohne asyncio
websockets installieren und festlegen
Dein Echo-Dienst aus Kapitel 5 funktioniert: Der handgebaute Client und der handgebaute Server stimmen bei jedem ws_handshake.py, ws_frames.py und loopback_demo.py, und ein Fehler, der auf beiden Seiten auf dieselbe Weise gemacht wird, hebt sich auf, so wie es eine 16-Bit-Länge getan hätte, die in Kapitel 3 von beiden
Dieses Kapitel bringt die Bibliothek websockets ins Spiel, von anderen Leuten nach demselben RFC 6455 geschrieben. Zuerst testet sie deinen Code; ab Lektion 2 übernimmt sie die Infrastruktur.
Der Projektbaum enthält die fertigen Versionen des Kurses von loopback_demo.py, ws_frames.py und ws_handshake.py, sodass das Kapitel von bekannten Dateien ausgeht, egal wie dein eigener Code aus Kapitel 5 aussah; nichts in diesem Kapitel ändert sie. Ab Lektion 2 schreibst du echo_library.py, und Run startet in den Editor-Lektionen library_demo.py.
Welche Version hier ist
Diese Lektion hat ein
python -c "import websockets; print(websockets.__version__)"
Es sollte 17.4 ausgeben, die Version, mit der dieser Kurs geprüft wurde und die die Sandbox der Website hat. Diese Kopie ist für das Python der Sandbox installiert, also kann jede spätere Lektion import websockets ausführen, ohne etwas zu installieren.
Festlegen
requirements.txt enthält bereits eine Zeile, pytest==9.1.1. Öffne die Datei im Tab Project oder wie in Python in der Praxis mit nano requirements.txt in der Shell und füge die Bibliothek darunter hinzu, sodass die Datei so lautet:
pytest==9.1.1
websockets==17.4
Das == legt die genaue Version fest. Bibliotheken ändern sich zwischen Releases: Einige pip install -r requirements.txt dann die Bibliothek, die dieses Kapitel verwendet.
Warum websockets==17.4 schreiben statt websockets?
Sichtbar installieren
Beweise jetzt, dass die Datei genügt, um die Umgebung neu aufzubauen. Erstelle eine neue
python -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
echo $?
.venv/bin/python -m pip freeze
pip liest beide Zeilen und installiert aus dem Paketspiegel des Kurses, und echo $? gibt seinen Exit-Code aus, 0, wenn die Installation funktioniert hat. Auf der Website war der Status 0, und pip freeze hat pytest und die Pakete, die pytest braucht, aufgelistet, und die Zeile websockets==17.4. Frag dann die neue Umgebung, welche Version sie bekommen hat:
.venv/bin/python -c "import websockets; print(websockets.__version__)"
Lokal hat es 17.4 ausgegeben, dieselbe Version, die das eigene Python der Sandbox melden sollte.
Wenn die Installation stattdessen scheitert, gibt pip einen Fehler aus, echo $? gibt einen anderen Status als 0 aus, und pip freeze zeigt keine
Die Website speichert .venv nie. Erzeugte Verzeichnisse werden beim Speichern deines Projekts ausgelassen, wie Python in der Praxis gezeigt hat, also ist die Umgebung, die du gerade gebaut hast, in der nächsten Lektion weg. Spätere Lektionen verwenden die Kopie, die für das Python der Sandbox installiert ist, und das ist dieselbe Version. Die Festlegung ist für deinen eigenen Rechner und für jeden, der dieses Projekt nach dir installiert.
Du öffnest die nächste Lektion. Ist dein .venv noch da?
Die Bibliothek trifft deinen Server
Öffne interop.py und lies es; jedes Warten darin ist begrenzt. Es startet den Server aus Kapitel 5, loopback_demo.serve_clients, in einem Thread für einen Client auf 127.0.0.1 connect(...) aus websockets.sync.client, sendet eine Text- und eine Binärnachricht und liest jedes Echo, sendet einen with-Block, was die Verbindung schließt. In Lektion 3 schreibst du einen Client wie diesen. Führe es aus:
python interop.py
Ein Lauf dieser Dateien auf der Website hat Folgendes ausgegeben. PORT steht für die Portnummer, die das System gewählt hat; deine wird abweichen:
interop: the Chapter 5 server is listening on 127.0.0.1:PORT
library client: the handshake succeeded
library client: echo 'hello from the websockets library'
library client: echo b'\x00\x01\x02'
library client: ping answered: True
library client: closed the connection
Chapter 5 server: [{'messages': 2, 'code': 1000}]
interop: server thread still running: False
Lies es Zeile für Zeile. Der check_upgrade hat mit einer 101 geantwortet, die den von accept_value berechneten Accept-check_accept_response tut. Die beiden Echos werden mit repr ausgegeben, das einen Wert so schreibt, wie er im Python-Quelltext stünde: Anführungszeichen um einen str, ein b vor bytes. Die Bibliothek hat also einen Text-Frame und einen binären Frame maskiert, der Server aus Kapitel 5 hat sie demaskiert und dekodiert, und die Echos kamen als Text und als binär zurück. Der Ping wurde beantwortet: Die Bibliothek hat einen Ping mit b"interop" gesendet, server_reply hat mit einem Pong mit denselben Bytes geantwortet, und das Warten hat innerhalb seiner 2 Sekunden True zurückgegeben. Das Verlassen des Blocks hat Close 1000 gesendet, und der eigene Bericht des Servers zeigt, dass er diesen Close wiederholt hat: zwei Nachrichten, Code 1000. Zuletzt war der Server-Thread beendet.
Um deinen eigenen Code aus Kapitel 5 in diesem Lauf zu sehen, kopiere die Datei des Kurses mit cp loopback_demo.py course_loopback_demo.py beiseite, füge deine über loopback_demo.py ein und führe python interop.py erneut aus. Nichts prüft diesen Lauf; stelle danach mit cp course_loopback_demo.py loopback_demo.py die Version des Kurses wieder her, weil spätere Lektionen sie verwenden.
Was zeigt der Interop-Lauf?
Deine Arbeit prüfen
Klicke auf Check my work. Es liest requirements.txt und sonst nichts: genau eine websockets-Zeile, websockets==17.4, und die Zeile pytest==9.1.1 muss noch da sein; Kommentare und Leerzeilen sind in Ordnung. Es sieht sich weder .venv an, das nicht gespeichert wird, noch den Interop-Lauf.
Die Bibliothek hat mit deinem Server geredet und mit ihm übereingestimmt. In der nächsten Lektion kehren sich die Rollen um: Dein Server aus Kapitel 5 wird zu einem Server der Bibliothek, einem Handler von ein paar Zeilen.
Aufgabe
Lege die Bibliothek in requirements.txt fest: Füge die Zeile websockets==17.4 hinzu und behalte die Zeile pytest==9.1.1.
Dann im
python -c "import websockets; print(websockets.__version__)", um die eigene Version der Sandbox zu sehen;python -m venv .venvund.venv/bin/python -m pip install -r requirements.txt, um aus dem Paketspiegel des Kurses zu installieren;.venv/bin/python -m pip freeze, und such nachwebsockets==17.4;python interop.py, um zuzusehen, wie der Client der Bibliothek mit dem Server aus Kapitel 5 redet.
Klicke auf Check my work, wenn die Festlegung in der Datei steht. Die Prüfung liest nur requirements.txt: Sie erwartet genau eine Zeile, die websockets==17.4, ohne >= oder ~= und nicht nur in einem Kommentar, und sie erwartet, dass pytest==9.1.1 noch da ist. Kommentare, Leerzeilen und die Reihenfolge der beiden Zeilen sind dir überlassen. Die Prüfung sieht sich weder .venv an, das die Website nicht speichert, noch das, was interop.py ausgegeben hat.