Websocket Support für Django – Channels

Schon lange juckt es mich in den Fingern mal etwas mit Websockets zu machen. Ich habe mich bereits etwas in den Client Teil dazu eingelesen, aber auf Server Seite kam ich bisher noch nie dazu mich dem Thema wirklich anzunehmen.

Ich wusste dass es z.B. mit Java oder node.js guten Support für Websockets gibt, meine aktuellen Projekte liefen aber alle mit Django und dort konnte ich bisher nie irgendwas schlaues finden zu diesem Thema – bis jetzt!

Mit Hack Zurich vor der Tür kam ich mit einem Kollegen im Brainstorming auch eben wieder genau auf diese Websocket Thematik zu sprechen.

Angeregt vom Gespräch machte ich mich im Anschluss gleich daran zu recherchieren, was denn die komfortabelste serverseitige Lösung für Websockets wäre. Dabei kam ich wieder auf node.js und irgendwelche Java Implementationen.

Nun wollte ich es doch nochmals wissen, gab es tatsächlich keine Möglichkeit Websockets auch mit Django zu nutzen? Immerhin schimpft sich Django ein Webframework für Minimalisten mit Deadlines zu sein und Websockets sollten da doch wohl auch zur Ausstattung gehören?

Django Channels

Und siehe da! Scheinbar wurde erst auf der Pycon 2016 eine Lösung dafür präsentiert und zwar von keinem geringeren als Andrew Godwin, einem Core Entwickler von Django, der unter anderem auch für South (das Datenbank-Migrations-Tool von Django) verantwortlich war.

Kurzum: Godwin hat ein Projekt gestartet welches momentan noch nicht zum Django Core gehört, dies jedoch in Zukunft möglicherweise wird.

Alle Infos zum Projekt findet man auf https://channels.readthedocs.io

Ich versuche hier die wichtigsten Infos aus der Dokumentation zu wiedergeben. Für weitere Details lohnt sich ein Blick in die Doku selber.

Django Channels ist eine Django app, welche eine neue Ebene zu Django hinzufügt, die es erlaubt WebSockets zu verwalten. Die App teilt Django in zwei Prozess Typen:

  • Einer der HTTP und Websockets verwaltet
  • Einer der Views, Websocket Handlers und Hintergrundtasks ausführt (Consumer)

Diese Prozesse kommunizieren über ein Protokoll namens ASGI (Asynchronous Server Gateway Interface), welches ähnlich funktioniert wie WSGI (Web Server Gateway Interface), aber über ein Netzwerk läuft und weitere Protokoll Typen erlaubt.

Was ist ein Channel?

Das Herzstück des Systems ist eine Datenstruktur namens channel. Es ist eine geordnete First-In-First-Out (FIFO) Queue mit message expiry (Nachrichten Verfall) bei der Nachrichten höchstens einmal zugestellt werden und zwar nur an einen Listener aufs Mal.

Channels werden nach Producer / Consumer Pattern genutzt, wie eine Task Queue. Der Producer schickt eine Nachricht an den Channel und werden dann von nur einem der wartenden Consumer abgeholt.

Innerhalb eines Netzwerks werden Channels über einen Namen identifiziert. Schreiben mehrere Maschinen in einen Channel mit demselben Namen, so schreiben sie in denselben Channel.

Gruppen

Channels sind immer nur zwischen zwei Maschinen (One to One) Deshalb braucht man Gruppen um gleichzeitig mehrere Maschinen zu bedienen. Es ist möglich mehrere Channels in einer Gruppe zusammenzufassen.

Channel Implementationen

Es gibt verschiedene Channel Implementationen die verwendet werden können. Standardmässig wird die in-memory Variante verwendet. Diese speichert ganz einfach alle Daten in einem dict im Memory und ist deshalb auch nicht cross-process fähig. Das funktioniert deshalb eigentlich nur im runserver Modus.

Eine Variante für das produktive Umfeld mit cross-process Unterstützung ist das Redis Backend asgi_redis.

Dieses muss zuerst installiert

pip install asgi_redis

und danach konfiguriert werden

# In settings.py
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgi_redis.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("localhost", 6379)],
        },
        "ROUTING": "myproject.routing.channel_routing",
    },
}

Wie nutzen wir Channels?

Es gibt bereits einige gute Tutorials wie man mithilfe von Channels in kurzer Zeit eine eigene Chat Applikation bauen kann:

An Introduction to WebSockets

Quellen / weitere Infos

http://www.html5rocks.com/en/tutorials/websockets/basics/

Ein Gedanke zu „Websocket Support für Django – Channels“

Leave a Reply