Skip to content

Instantly share code, notes, and snippets.

@duplxey
Last active December 31, 2023 08:44
Show Gist options
  • Save duplxey/095d2abd25cef0b58c4aa724bab6fb70 to your computer and use it in GitHub Desktop.
Save duplxey/095d2abd25cef0b58c4aa724bab6fb70 to your computer and use it in GitHub Desktop.
[testdriven.io] Channels tutorial > Join & leave messages
import json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
from chat.models import Room, Message
class ChatConsumer(WebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(args, kwargs)
self.room_name = None
self.room_group_name = None
self.room = None
self.user = None
def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = f'chat_{self.room_name}'
self.room = Room.objects.get(name=self.room_name)
self.user = self.scope['user']
# connection has to be accepted
self.accept()
# join the room group
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name,
)
# -------------------- new --------------------
# send the user list to the newly joined user
self.send(json.dumps({
'type': 'user_list',
'users': [user.username for user in self.room.online.all()],
}))
if self.user.is_authenticated:
# send the join event to the room
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'user_join',
'user': self.user.username,
}
)
self.room.online.add(self.user)
# ---------------- end of new ----------------
def disconnect(self, close_code):
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name,
)
# -------------------- new --------------------
if self.user.is_authenticated:
# send the leave event to the room
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'user_leave',
'user': self.user.username,
}
)
self.room.online.remove(self.user)
# ---------------- end of new ----------------
def receive(self, text_data=None, bytes_data=None):
text_data_json = json.loads(text_data)
message = text_data_json['message']
if not self.user.is_authenticated:
return
# send chat message event to the room
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'chat_message',
'user': self.user.username,
'message': message,
}
)
Message.objects.create(user=self.user, room=self.room, content=message)
def chat_message(self, event):
self.send(text_data=json.dumps(event))
# -------------------- new --------------------
def user_join(self, event):
self.send(text_data=json.dumps(event))
def user_leave(self, event):
self.send(text_data=json.dumps(event))
# ---------------- end of new ----------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment