WEBSOCKET.md
March 31, 2026 · View on GitHub
Table of Contents | ← Webhooks | Messaging →
WebSocket
The following is the supplementary content to the WebSocket chapter. The examples in this chapter show how to work with the WFS' WebSocket APIs.
Requirements
Lab Setup
The setup steps in this section are executed relative to the root of the book's code repository and must be performed only once.
These steps will create three Docker containers: django-app, django-postgres, and django-redis.
cd src/django
docker compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g)
docker compose up --detach --wait
Visit app at http://localhost:8000
Important
When working with GitHub Codespaces, you'll use a unique URL containing the Codespace's name instead of the localhost URL.
Inspecting WebSocket protocol with Wireshark
This example shows captured with Wireshark traffic between the WebSocket client and server. The JavaScript client code is downloaded by the browser from the Django server located at http://localhost:8000/ws/v1/echo. Note that the connection is unencrypted, and the WebSocket protocol is visible in the captured packets. An encrypted WebSocket connection is described in the security section.
WFS Alerting
The following example shows how to send an alert message to WebSocket clients.
The alert message is sent using the app_alert command.
The command takes two arguments: the --city-uuid, which is the UUID of the city to which the alert message is sent, and the --message argument that describes the alert message.
To demonstrate that alerting works, two WebSocket clients (Firefox and Chrome web browsers) receive alerts from the WebSocket server.
Warning
Remember to adjust the UUID of the city to match the UUID of the city you use in your local environment.
# Get UUID of the first city
CITY_UUID=$(docker compose exec app python manage.py app_cities | head -n 1 | cut -d' ' -f 2)
# Issue an alert message
docker compose exec app python manage.py app_alert --city-uuid=$CITY_UUID --message 'Hail storm is coming!'
Security
This section demonstrates WebSocket encryption.
Transport Layer Security
The following example shows how to set up and test TLS encryption for WebSocket. The example uses a client (JavaScript client code downloaded by the browser from the Django server at port 8000) that sends an "echo" message to the WebSocket server (port 8001) and receives the message back.
To enable TLS in the local environment edit src/django/compose.yaml to set TLS_ENABLE environment variable to 1, and restart the Docker containers.
An encrypted WebSocket connection is visible in the browser as the wss:// protocol.
# Enable TLS
sed --in-place 's/- TLS_ENABLE=0/- TLS_ENABLE=1/g' compose.yaml
# Restart containers
docker compose up --detach --wait
Important
When working in GitHub Codespaces, you need to change the visibility of WebSocket server port 8001 to Public, and disable TLS by setting the +TLS_ENABLE+ variable to +0+ (src/django/compose.yaml). TLS in GitHub Codespaces comes out of the box.
When visiting https://localhost:8000 locally (not in GitHub Codespaces), the browser will display a warning: "Your connection is not private" in Chrome and "Warning: Potential Security Risk Ahead" in Firefox. To interact with the WFS web page, add the application's self-signed SSL certificate to the browser's exception list. To do this, visit https://localhost:8000 as well as https://localhost:8001, and depending on what web browser you are using, click "Proceed to localhost (unsafe)" in Chrome or "Accept the risk and continue" in Firefox.
Documentation
The following example shows how to generate documentation for the WebSocket API using AsyncAPI. The AsyncAPI documentation is generated as an HTML file from the src/django/docs/api/websocket/v1-schema.yaml file. The generated documentation is available in the src/django/docs/api/websocket/output directory.
# Change the location to the directory that contains the AsyncAPI schema
cd src/django/docs/api/websocket
# Generate HTML documentation using the _asyncapi/cli_ Docker image
docker run --rm -it \
--volume ${PWD}/output:/app/output \
--volume ${PWD}/v1-schema.yaml:/app/asyncapi.yaml \
asyncapi/cli generate fromTemplate /app/asyncapi.yaml \
@asyncapi/html-template \
--force-write --output /app/output
# Serve the generated HTML documentation using the Nginx web server
docker run --rm --detach --publish 127.0.0.1:8888:80 \
--volume ${PWD}/output:/usr/share/nginx/html:ro nginx
Lab Teardown
The following command stops and removes the Docker containers created in the lab setup step.
docker compose down




