Skip to content

django channels

Tip
pip install django
pip install channels
pip install daphne
pip install channels_redis

# or
pip install django channels daphne

# Start the Daphne server:
daphne -p 8005 myproject.asgi:application
settings.py
INSTALLED_APPS = [
    # ...
    'channels',
    # ...
]

# WSGI application
WSGI_APPLICATION = 'your_project_name.wsgi.application'

# ASGI application
ASGI_APPLICATION = 'your_project_name.asgi.application'

# Channels layer backend
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}
asgi.py
routing.py
consumers.py

Channels is a Django extension that allows us to use protocols other than HTTP. The Django team, knowing the existing limitations of including other protocols, had to create a new server called Daphne that is natively compatible with the Asynchronous Server Gateway Interface (ASGI), an update of the Web Server Gateway Interface (WSGI). Without Channels, it would be impossible to have the WebSockets protocol.

Why Do We Need WebSockets?

WebSockets are essential for enabling real-time, two-way communication between a client and a server. Traditional HTTP protocols are request-response based, which means a client must send a request and wait for a response from the server. This model is not ideal for applications requiring real-time updates, such as chat applications, live sports scores, online gaming, or collaborative tools.

Problems Solved by WebSockets

  1. Real-Time Communication: WebSockets allow for instantaneous data transfer between client and server without the need for repeated HTTP requests.
  2. Efficiency: Once a WebSocket connection is established, it remains open, reducing the overhead of establishing new connections and improving the efficiency of data transfer.
  3. Low Latency: WebSockets reduce the latency of data transfer compared to HTTP, which is crucial for applications where timing is critical.
  4. Bi-Directional Communication: Unlike HTTP, where the client always initiates communication, WebSockets support two-way communication, allowing the server to push updates to the client.

When to Use WebSockets

  1. Chat Applications: For real-time messaging between users.
  2. Live Notifications: For pushing updates such as news alerts, notifications, or messages.
  3. Real-Time Gaming: For synchronizing game states and user actions in multiplayer games.
  4. Collaborative Tools: For live updates in collaborative documents or whiteboards.
  5. Financial Tickers: For real-time stock or cryptocurrency price updates.

django channels image

Sure, let's create a real-time example of push notifications in Django using Django Channels and Daphne. We'll set up a simple project where messages sent from one client are broadcast to all connected clients in real time.

Example

Step-by-Step Guide

  1. Install Required Packages

    First, install Django and Django Channels:

    bash

    pip install django channels daphne
    
  2. Create Django Project and Application

    Create a new Django project and an application within it:

    bash

    django-admin startproject myproject
    cd myproject
    django-admin startapp myapp
    
  3. Configure Django Channels

    Edit myproject/settings.py to include channels in your INSTALLED_APPS and configure the ASGI application and channel layers:

    settings.py

    INSTALLED_APPS = [
        ...
        'channels',
        ...
        # Other installed apps
        'myapp',
    ]
    
    ASGI_APPLICATION = 'myproject.asgi.application'
    
    CHANNEL_LAYERS = {
        'default': {
            'BACKEND': 'channels.layers.InMemoryChannelLayer',
        },
    }
    
  4. Create ASGI Configuration

    Create an asgi.py file in your project directory:

    myproject/asgi.py
    import os
    from django.core.asgi import get_asgi_application
    from channels.routing import ProtocolTypeRouter, URLRouter
    from channels.auth import AuthMiddlewareStack
    import myapp.routing
    
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
    
    application = ProtocolTypeRouter({
        "http": get_asgi_application(),
        "websocket": AuthMiddlewareStack(
            URLRouter(
                myapp.routing.websocket_urlpatterns
            )
        ),
    })
    
  5. Define WebSocket Routing

    Create a routing.py file in your myapp directory:

    myapp/routing.py
    from django.urls import re_path
    from . import consumers
    
    websocket_urlpatterns = [
        re_path(r'ws/notifications/$', consumers.NotificationConsumer.as_asgi()),
    ]
    
  6. Create a Consumer

    Create a consumers.py file in your myapp directory:

    myapp/consumers.py
    import json
    from channels.generic.websocket import AsyncWebsocketConsumer
    
    class NotificationConsumer(AsyncWebsocketConsumer):
        async def connect(self):
            await self.channel_layer.group_add("notifications", self.channel_name)
            await self.accept()
    
        async def disconnect(self, close_code):
            await self.channel_layer.group_discard("notifications", self.channel_name)
    
        async def receive(self, text_data):
            data = json.loads(text_data)
            message = data['message']
    
            await self.channel_layer.group_send(
                "notifications",
                {
                    'type': 'send_notification',
                    'message': message
                }
            )
    
        async def send_notification(self, event):
            message = event['message']
            await self.send(text_data=json.dumps({
                'message': message
            }))
    
  7. Set Up URLs

    Create the app's urls.py file:

    myapp/urls.py
    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('', views.index, name='index'),  # This will render the HTML page
    ]
    

    Update the project-level urls.py:

    myproject/urls.py
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', include('myapp.urls')),  # Include app URLs
    ]
    
  8. Create a View

    Create a simple view to render the index.html:

    myapp/views.py
    from django.shortcuts import render
    
    def index(request):
        return render(request, 'index.html')
    
  9. Create a Simple Frontend

    Create an index.html file in a templates directory inside your myapp directory:

    myapp/templates/index.html
    <!DOCTYPE html>
    <html>
    <head>
        <title>Push Notifications</title>
    </head>
    <body>
        <h1>Push Notifications Example</h1>
        <div id="notifications"></div>
        <input type="text" id="messageInput" placeholder="Enter a message">
        <button onclick="sendMessage()">Send</button>
    
        <script>
            const ws = new WebSocket('ws://' + window.location.host + '/ws/notifications/');
    
            ws.onmessage = function(event) {
                const data = JSON.parse(event.data);
                const notificationsDiv = document.getElementById('notifications');
                notificationsDiv.innerHTML += '<p>' + data.message + '</p>';
            };
    
            function sendMessage() {
                const messageInput = document.getElementById('messageInput');
                const message = messageInput.value;
                ws.send(JSON.stringify({ 'message': message }));
                messageInput.value = '';
            }
        </script>
    </body>
    </html>
    

Running the Server

  1. Run the Daphne server: Start the Daphne server to handle HTTP and WebSocket connections:

    bash
    daphne -p 8000 myproject.asgi:application
    
  2. Navigate to the site: Open your browser and go to http://localhost:8000/. You should see the HTML page with an input box and a button.

  3. Test the real-time notifications:

    • Open multiple browser tabs or windows to http://localhost:8000/.
    • Enter a message in the input box and click the "Send" button.
    • The message should appear in real-time on all open tabs or windows.

Summary

This example demonstrates how to set up real-time push notifications in a Django project using Django Channels and Daphne. The steps include configuring Django Channels, setting up ASGI, defining WebSocket routing, creating a WebSocket consumer, and building a simple frontend to send and receive messages in real-time. By following these steps, you can implement real-time communication in your Django applications.


Reference