Channel Layers In Django – Auriga
- General
Channel Layers In Django – Auriga
Channels Layers In Django
Channel Layers allow us to create interaction between different instances of an application, mostly used to create real-time applications, we can say it’s an alternative to sockets. Channel Layers are purely async interfaces (for both sender and receiver), you have to wrap them in a wrapper container if you want them to behave synchronously.
Channel Layer configurations
You can configure Channel Layer via CHANNEL_LAYERS in the settings file. you can get the default channel layer in your project with
1 |
channels.layers.get_channel_layer() |
In case are in consumer you can get it with
1 |
self.channel_layer |
Redis Channel Layer – (Channels Layers in Django)
channel_redis is the only official Django-maintained channel layer support for production use. Redis Channel layer uses redis as its backing store. you can configure it by putting the below configurations in your settings file.
Code Example, when Redis is running on localhost (127.0.0.2) and on port (6379
1 2 3 4 5 6 7 8 |
CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [("127.0.0.1", 6379)], }, }, } |
In Memory Channel Layer- (Channels Layers in Django)
we can also use channels with In-memory store by using In-Memory Channel Layer, you can configure it by putting the following piece of code in your settings file.
1 2 3 4 5 |
CHANNEL_LAYERS = { "default": { "BACKEND": "channels.layers.InMemoryChannelLayer" } } |
Implementation of Channel layers with an example
for more understanding with Channel layers in Django let’s discuss and Chat room example.
Let’s create an app for Chat room.
1 2 3 4 5 6 7 8 9 10 11 |
python3 manage.py startapp chat chat/ __init__.py admin.py apps.py migrations/ __init__.py models.py tests.py views.py |
adding creating app to installed_apps in settings file
1 2 3 4 5 6 7 8 9 10 |
# mysite/settings.py INSTALLED_APPS = [ 'chat', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] |
creating a template as a output view.
1 2 3 4 5 6 |
chat/ __init__.py templates/ chat/ index.html views.py |
put the following code in chat/templates/chat/index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<!-- chat/templates/chat/index.html --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Chat Rooms</title> </head> <body> What chat room would you like to enter?<br> <input id="room-name-input" type="text" size="100"><br> <input id="room-name-submit" type="button" value="Enter"> <script> document.querySelector('#room-name-input').focus(); document.querySelector('#room-name-input').onkeyup = function(e) { if (e.keyCode === 13) { // enter, return document.querySelector('#room-name-submit').click(); } }; document.querySelector('#room-name-submit').onclick = function(e) { var roomName = document.querySelector('#room-name-input').value; window.location.pathname = '/chat/' + roomName + '/'; }; </script> </body> </html> |
now rendering template as view by adding following code in chat/views.py
1 2 3 4 5 |
# chat/views.py from django.shortcuts import render def index(request): return render(request, 'chat/index.html') |
URL configurations for the above-rendered view by putting the following code in chat/urls.py
1 2 3 4 5 6 7 8 |
# chat/urls.py from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), ] |
Including Chat app URL configurations to main URL configurations
1 2 3 4 5 6 7 8 9 |
# mysite/urls.py from django.conf.urls import include from django.urls import path from django.contrib import admin urlpatterns = [ path('chat/', include('chat.urls')), path('admin/', admin.site.urls), ] |
Integrating Channel library
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# mysite/asgi.py import os from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application import chat.routing os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": AuthMiddlewareStack( URLRouter( chat.routing.websocket_urlpatterns ) ), }) |
configuring channels by putting the following code in my settings file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# mysite/settings.py INSTALLED_APPS = [ 'channels', 'chat', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] # mysite/settings.py # Channels ASGI_APPLICATION = 'mysite.asgi.application' |
adding chat room template in chat/templates/chat/room.html file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
chat/ __init__.py templates/ chat/ index.html room.html urls.py views.py <!-- chat/templates/chat/room.html --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Chat Room</title> </head> <body> <textarea id="chat-log" cols="100" rows="20"></textarea><br> <input id="chat-message-input" type="text" size="100"><br> <input id="chat-message-submit" type="button" value="Send"> {{ room_name|json_script:"room-name" }} <script> const roomName = JSON.parse(document.getElementById('room-name').textContent); const chatSocket = new WebSocket( 'ws://' + window.location.host + '/ws/chat/' + roomName + '/' ); chatSocket.onmessage = function(e) { const data = JSON.parse(e.data); document.querySelector('#chat-log').value += (data.message + '\n'); }; chatSocket.onclose = function(e) { console.error('Chat socket closed unexpectedly'); }; document.querySelector('#chat-message-input').focus(); document.querySelector('#chat-message-input').onkeyup = function(e) { if (e.keyCode === 13) { // enter, return document.querySelector('#chat-message-submit').click(); } }; document.querySelector('#chat-message-submit').onclick = function(e) { const messageInputDom = document.querySelector('#chat-message-input'); const message = messageInputDom.value; chatSocket.send(JSON.stringify({ 'message': message })); messageInputDom.value = ''; }; </script> </body> </html> |
rendering chat room view in chat/views.py
1 2 3 4 5 6 7 8 9 10 |
# chat/views.py from django.shortcuts import render def index(request): return render(request, 'chat/index.html', {}) def room(request, room_name): return render(request, 'chat/room.html', { 'room_name': room_name }) |
adding URL for chat room in URL file( chat/urls.py)
1 2 3 4 5 6 7 8 |
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), path('<str:room_name>/', views.room, name='room'), ] |
now we have to create a consumer to control this whole process as in the chat/consumers.py file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
chat/ __init__.py consumers.py templates/ chat/ index.html room.html urls.py views.py import json from channels.generic.websocket import WebsocketConsumer class ChatConsumer(WebsocketConsumer): def connect(self): self.accept() def disconnect(self, close_code): pass def receive(self, text_data): text_data_json = json.loads(text_data) message = text_data_json['message'] self.send(text_data=json.dumps({ 'message': message })) |
as to configure above consumer with and URL we have to define URL routing in chat/routing.py file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
chat/ __init__.py consumers.py routing.py templates/ chat/ index.html room.html urls.py views.py from django.urls import re_path from . import consumers websocket_urlpatterns = [ re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()), ] |
here we go now run command python manage.py runserver and hit URL “/chat-room/”, by doing so you can visit a chat room, if you are opening the same URL in two different tabs, you are able to pass the messages in between two tabs without page load.
Related content
Auriga: Leveling Up for Enterprise Growth!
Auriga’s journey began in 2010 crafting products for India’s