35
loading...
This website collects cookies to deliver better user experience
Channel layers allow you to talk between different instances of an application. They’re a useful part of making a distributed real-time application if you don’t want to have to shuttle all of your messages or events through a database.
channels_redis
and InMemoryChannelLayer
. InMemoryChannelLayer
as a channel layer for the chat app, I'll show you how you can set up channels_redis
as well.channels_redis
is an officially maintained channel layer that uses Redis as its backing store. channels_redis
uses Redis as its backing store.channels_redis
package in the chat app so that Django channels knows how to interface with redis.pip install channels_redis
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("127.0.0.1", 6379)],
},
},
}
In-memory channel layers operate with each process as a separate layer. This means that no cross-process messaging is possible. As the core value of channel layers is to provide distributed messaging, in-memory usage will result in sub-optimal performance, and ultimately data-loss in a multi-instance environment.
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
}
}
from django.urls import path
from . import views
urlpatterns = [
path('<str:room_name>/', views.room, name='room'),
]
room_name
to be used in a view function, we captured it as you can see from the above code. The url parameter (room_name
) is only captured if the provided value matches the given path converter which is str
for string.from django.shortcuts import render
def room(request, room_name):
return render(request, 'chat/room.html', {
'room_name': room_name
})
room_name
which is the parameter passed by the url. It's important to note that the names of url parameters must match the names of the view method arguments.room_name
, it will pass it to the room template for presentation.<!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
+ '/'
);
// onmessage - An event listener to be called when a message is received from the server.
chatSocket.onmessage = function(e) {
// JSON.parse() converts the JSON object back into the original object,
// then examine and act upon its contents.
const data = JSON.parse(e.data);
document.querySelector('#chat-log').value += (data.message + '\n');
};
// onclose - An event listener to be called when the connection is closed.
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;
// Send the msg object as a JSON-formatted string.
chatSocket.send(JSON.stringify({
'message': message
}));
// Blank the text input element, ready to receive the next line of text from the user.
messageInputDom.value = '';
};
</script>
</body>
</html>
room_name
that is passed to it by the view. The template filter json_script
outputs the Python object (room_name
) as JSON inside of our script.room-name
and created a WebSocket connection within that room ws://127.0.0.1:8000/ws/chat/room-name/
.python manage.py runserver
http://127.0.0.1:8000/chat/hannah/