committed by
GitHub
1 changed files with 224 additions and 0 deletions
@ -0,0 +1,224 @@ |
|||||
|
# WebSockets |
||||
|
|
||||
|
Sie können <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a> mit **FastAPI** verwenden. |
||||
|
|
||||
|
## `WebSockets` installieren |
||||
|
|
||||
|
Zuerst müssen Sie `WebSockets` installieren: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ pip install websockets |
||||
|
|
||||
|
---> 100% |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
## WebSockets-Client |
||||
|
|
||||
|
### In Produktion |
||||
|
|
||||
|
In Ihrem Produktionssystem haben Sie wahrscheinlich ein Frontend, das mit einem modernen Framework wie React, Vue.js oder Angular erstellt wurde. |
||||
|
|
||||
|
Und um über WebSockets mit Ihrem Backend zu kommunizieren, würden Sie wahrscheinlich die Werkzeuge Ihres Frontends verwenden. |
||||
|
|
||||
|
Oder Sie verfügen möglicherweise über eine native Mobile-Anwendung, die direkt in nativem Code mit Ihrem WebSocket-Backend kommuniziert. |
||||
|
|
||||
|
Oder Sie haben andere Möglichkeiten, mit dem WebSocket-Endpunkt zu kommunizieren. |
||||
|
|
||||
|
--- |
||||
|
|
||||
|
Für dieses Beispiel verwenden wir jedoch ein sehr einfaches HTML-Dokument mit etwas JavaScript, alles in einem langen String. |
||||
|
|
||||
|
Das ist natürlich nicht optimal und man würde das nicht in der Produktion machen. |
||||
|
|
||||
|
In der Produktion hätten Sie eine der oben genannten Optionen. |
||||
|
|
||||
|
Aber es ist die einfachste Möglichkeit, sich auf die Serverseite von WebSockets zu konzentrieren und ein funktionierendes Beispiel zu haben: |
||||
|
|
||||
|
```Python hl_lines="2 6-38 41-43" |
||||
|
{!../../../docs_src/websockets/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
## Einen `websocket` erstellen |
||||
|
|
||||
|
Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`: |
||||
|
|
||||
|
```Python hl_lines="1 46-47" |
||||
|
{!../../../docs_src/websockets/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
!!! note "Technische Details" |
||||
|
Sie können auch `from starlette.websockets import WebSocket` verwenden. |
||||
|
|
||||
|
**FastAPI** stellt den gleichen `WebSocket` direkt zur Verfügung, als Annehmlichkeit für Sie, den Entwickler. Er kommt aber direkt von Starlette. |
||||
|
|
||||
|
## Nachrichten erwarten und Nachrichten senden |
||||
|
|
||||
|
In Ihrer WebSocket-Route können Sie Nachrichten `await`en und Nachrichten senden. |
||||
|
|
||||
|
```Python hl_lines="48-52" |
||||
|
{!../../../docs_src/websockets/tutorial001.py!} |
||||
|
``` |
||||
|
|
||||
|
Sie können Binär-, Text- und JSON-Daten empfangen und senden. |
||||
|
|
||||
|
## Es ausprobieren |
||||
|
|
||||
|
Wenn Ihre Datei `main.py` heißt, führen Sie Ihre Anwendung so aus: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uvicorn main:app --reload |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Öffnen Sie Ihren Browser unter <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>. |
||||
|
|
||||
|
Sie sehen eine einfache Seite wie: |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image01.png"> |
||||
|
|
||||
|
Sie können Nachrichten in das Eingabefeld tippen und absenden: |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image02.png"> |
||||
|
|
||||
|
Und Ihre **FastAPI**-Anwendung mit WebSockets antwortet: |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image03.png"> |
||||
|
|
||||
|
Sie können viele Nachrichten senden (und empfangen): |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image04.png"> |
||||
|
|
||||
|
Und alle verwenden dieselbe WebSocket-Verbindung. |
||||
|
|
||||
|
## Verwendung von `Depends` und anderen |
||||
|
|
||||
|
In WebSocket-Endpunkten können Sie Folgendes aus `fastapi` importieren und verwenden: |
||||
|
|
||||
|
* `Depends` |
||||
|
* `Security` |
||||
|
* `Cookie` |
||||
|
* `Header` |
||||
|
* `Path` |
||||
|
* `Query` |
||||
|
|
||||
|
Diese funktionieren auf die gleiche Weise wie für andere FastAPI-Endpunkte/*Pfadoperationen*: |
||||
|
|
||||
|
=== "Python 3.10+" |
||||
|
|
||||
|
```Python hl_lines="68-69 82" |
||||
|
{!> ../../../docs_src/websockets/tutorial002_an_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
=== "Python 3.9+" |
||||
|
|
||||
|
```Python hl_lines="68-69 82" |
||||
|
{!> ../../../docs_src/websockets/tutorial002_an_py39.py!} |
||||
|
``` |
||||
|
|
||||
|
=== "Python 3.8+" |
||||
|
|
||||
|
```Python hl_lines="69-70 83" |
||||
|
{!> ../../../docs_src/websockets/tutorial002_an.py!} |
||||
|
``` |
||||
|
|
||||
|
=== "Python 3.10+ nicht annotiert" |
||||
|
|
||||
|
!!! tip "Tipp" |
||||
|
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
||||
|
|
||||
|
```Python hl_lines="66-67 79" |
||||
|
{!> ../../../docs_src/websockets/tutorial002_py310.py!} |
||||
|
``` |
||||
|
|
||||
|
=== "Python 3.8+ nicht annotiert" |
||||
|
|
||||
|
!!! tip "Tipp" |
||||
|
Bevorzugen Sie die `Annotated`-Version, falls möglich. |
||||
|
|
||||
|
```Python hl_lines="68-69 81" |
||||
|
{!> ../../../docs_src/websockets/tutorial002.py!} |
||||
|
``` |
||||
|
|
||||
|
!!! info |
||||
|
Da es sich um einen WebSocket handelt, macht es keinen Sinn, eine `HTTPException` auszulösen, stattdessen lösen wir eine `WebSocketException` aus. |
||||
|
|
||||
|
Sie können einen „Closing“-Code verwenden, aus den <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">gültigen Codes, die in der Spezifikation definiert sind</a>. |
||||
|
|
||||
|
### WebSockets mit Abhängigkeiten ausprobieren |
||||
|
|
||||
|
Wenn Ihre Datei `main.py` heißt, führen Sie Ihre Anwendung mit Folgendem aus: |
||||
|
|
||||
|
<div class="termy"> |
||||
|
|
||||
|
```console |
||||
|
$ uvicorn main:app --reload |
||||
|
|
||||
|
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
||||
|
``` |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
Öffnen Sie Ihren Browser unter <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>. |
||||
|
|
||||
|
Dort können Sie einstellen: |
||||
|
|
||||
|
* Die „Item ID“, die im Pfad verwendet wird. |
||||
|
* Das „Token“, das als Query-Parameter verwendet wird. |
||||
|
|
||||
|
!!! tip "Tipp" |
||||
|
Beachten Sie, dass der Query-„Token“ von einer Abhängigkeit verarbeitet wird. |
||||
|
|
||||
|
Damit können Sie den WebSocket verbinden und dann Nachrichten senden und empfangen: |
||||
|
|
||||
|
<img src="/img/tutorial/websockets/image05.png"> |
||||
|
|
||||
|
## Verbindungsabbrüche und mehreren Clients handhaben |
||||
|
|
||||
|
Wenn eine WebSocket-Verbindung geschlossen wird, löst `await websocket.receive_text()` eine `WebSocketDisconnect`-Exception aus, die Sie dann wie in folgendem Beispiel abfangen und behandeln können. |
||||
|
|
||||
|
=== "Python 3.9+" |
||||
|
|
||||
|
```Python hl_lines="79-81" |
||||
|
{!> ../../../docs_src/websockets/tutorial003_py39.py!} |
||||
|
``` |
||||
|
|
||||
|
=== "Python 3.8+" |
||||
|
|
||||
|
```Python hl_lines="81-83" |
||||
|
{!> ../../../docs_src/websockets/tutorial003.py!} |
||||
|
``` |
||||
|
|
||||
|
Zum Ausprobieren: |
||||
|
|
||||
|
* Öffnen Sie die Anwendung mit mehreren Browser-Tabs. |
||||
|
* Schreiben Sie Nachrichten in den Tabs. |
||||
|
* Schließen Sie dann einen der Tabs. |
||||
|
|
||||
|
Das wird die Ausnahme `WebSocketDisconnect` auslösen und alle anderen Clients erhalten eine Nachricht wie: |
||||
|
|
||||
|
``` |
||||
|
Client #1596980209979 left the chat |
||||
|
``` |
||||
|
|
||||
|
!!! tip "Tipp" |
||||
|
Die obige Anwendung ist ein minimales und einfaches Beispiel, das zeigt, wie Nachrichten verarbeitet und an mehrere WebSocket-Verbindungen gesendet werden. |
||||
|
|
||||
|
Beachten Sie jedoch, dass, da alles nur im Speicher in einer einzigen Liste verwaltet wird, es nur funktioniert, während der Prozess ausgeführt wird, und nur mit einem einzelnen Prozess. |
||||
|
|
||||
|
Wenn Sie etwas benötigen, das sich leicht in FastAPI integrieren lässt, aber robuster ist und von Redis, PostgreSQL und anderen unterstützt wird, sehen Sie sich <a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a> an. |
||||
|
|
||||
|
## Mehr Informationen |
||||
|
|
||||
|
Weitere Informationen zu Optionen finden Sie in der Dokumentation von Starlette: |
||||
|
|
||||
|
* <a href="https://www.starlette.io/websockets/" class="external-link" target="_blank">Die `WebSocket`-Klasse</a>. |
||||
|
* <a href="https://www.starlette.io/endpoints/#websocketendpoint" class="external-link" target="_blank">Klassen-basierte Handhabung von WebSockets</a>. |
Loading…
Reference in new issue