Django Channels and its production deployment
Introduction
I had a task to prepare a real-time billing solution in one of our projects and we were using Django. Generally, it is a really great framework but the only issue with it is that it is synchronous. The solution that we wanted had to be real-time, hence I came across Channels using Django.
Channels is a project that takes Django and extends its abilities beyond HTTP — to handle WebSockets, chat protocols, IoT protocols, and provide real-time capabilities like chat and push notifications. It does this by taking the core of Django and layering a fully asynchronous layer underneath, running Django itself in asynchronous mode but handling connections and sockets asynchronously, and giving you the choice to write in either style. A channel is like a pipe. A sender sends a message to this pipe from one end and it reaches a listener at the other end.It’s built on a Python specification called ASGI(Asynchronous Gateway Protocol).
What is ASGI?
In production environments, the Django framework works on WSGI (Web Server Gateway Interface), which is an interface for python applications that can handle HTTP requests and spawn workers for handling requests. But for asynchronous applications, we need an interface like ASGI (Asynchronous Server Gateway Interface), that can handle WebSockets requests as well.
How a typical Django Channels infrastructure works
As Django channels work over ASGI servers like Daphene, it can handle both HTTP and WebSocket requests. An ASGI server handles HTTP requests synchronously that is server waits for the client to initiate a request and then handles the request and sends the response back to the client while it handles WebSocket's request asynchronously.As server uses an ASGI router that differentiates between an HTTP and WebSocket request. An HTTP request is sent to the view and a WebSocket request is sent to the consumer(rather than view). Some brokers that can be used as ASGI routers are-
- asgi_redis
- asgi_rabbitmq
- asgiref
What is Consumer?
A consumer is a class in which you can write both normal Python functions (synchronous) or awaitables (asynchronous). Consumers structures code as a series of functions to be called whenever an event happens, rather than making you write an event loop. Django Channels has inbuilt generic consumers that you can inherit. Various generic consumers are:
1.WebsocketConsumer
2.AsyncWebsocketConsumer
3.JsonWebsocketConsumer
4.AsyncHttpConsumer
Setup:
1. Pip install channels==1.0.2 channels_redis==1.0.0
2. sudo apt update and sudo apt install redis-server
3. Add channels in INSTALLED_APPS and set your ASGI_APPLICATION setting to point to that routing object as your root application in settings.py file:
4.Add channel_layer in settings.py file
5. Create asgi.py file
6. Create routing.py file
7. Create Consumer file that handles web socket requests
Django Channels Live Deployment
The Channels project maintains an official ASGI HTTP/WebSocket server, Daphne, You can choose to either use Daphne for all requests — HTTP and WebSocket — or keep running standard HTTP requests through a WSGI server and use Daphne only for things WSGI cannot do, like HTTP long-polling and WebSockets. If you do a split, you’ll need to put something in front of Daphne and your WSGI server to work out what requests to send to each (using HTTP path or domain) — that’s not covered here, just know you can do it. If you use Daphne for all traffic, it auto-negotiates between HTTP and WebSocket, so there’s no need to have your WebSockets on a separate domain or path (and they’ll be able to share cookies with your normal view code, which isn’t possible if you separate by domain rather than the path).To run Daphne, it just needs to be supplied with an application, much like a WSGI server would need to be. Make sure you have an asgi.py file as mentioned above.
Then, you can run Daphne and supply the channel layer as the argument:
Daphne myproject.asgi:application
You should run Daphne inside either a process supervisor (systemd, supervisord) or a container orchestration system (Kubernetes, nomad) to ensure that it gets restarted if needed and to allow you to scale the number of processes.
If you want to bind multiple Daphne instances to the same port on a machine, use a process supervisor that can listen on ports and pass the file descriptors to launch processes, and then pass the file descriptor with –fd NUM.
You can also specify the port and IP that Daphne binds to:
daphne -p 8001 -b 0.0.0.0 djws.asgi:application
Conclusion
Channels is a powerful library that helps you to build a real-time application without much effort and changes in your current application.It brings WebSocket and Http2 support. Channels allow you to standardize communications using WebSockets.Here are some links that might be helpful: