11# The below code is just for testing purposes (it works!)
22# Tested it using https://websocketking.com/
33# and entered ws://localhost:8000/ws/apps/chat/practice/
4- from channels .generic .websocket import AsyncJsonWebsocketConsumer
4+ import json
5+ from channels .generic .websocket import AsyncWebsocketConsumer
6+ from asgiref .sync import sync_to_async
7+ from .models import Message , Chat
8+ from django .contrib .auth .models import User
59
6- class PracticeConsumer (AsyncJsonWebsocketConsumer ):
7- async def connect (self ):
8- await self .accept ()
10+ # https://medium.com/@farad.dev/how-to-build-a-real-time-chat-app-using-django-channels-2ba2621ea972
11+ class ChatConsumer (AsyncWebsocketConsumer ):
912
10- async def receive (self , text_data = None , bytes_data = None , ** kwargs ):
11- if text_data == 'PING' :
12- # Send back a response
13- await self .send (text_data = '{"message": "PONG"}' )
13+ async def connect (self ):
14+ user_id = self .scope .get ('user_id' )
15+ if user_id is not None :
16+ self .user_id = user_id
17+ self .room_name = self .scope ["url_route" ]["kwargs" ]["room_name" ] # Extracts the room_name from the URL
18+ self .room_group_name = f'chat_{ self .room_name } '
19+
20+ await self .channel_layer .group_add ( # Adds the WebSocket connection (client) to a channel group
21+ self .room_group_name ,
22+ self .channel_name
23+ )
24+ await self .accept ("chat" ) # Returns protocol back to browser (DO NOT DELETE)
25+
26+
27+ async def disconnect (self , close_code ):
28+ print (f"Disconnected! Code: { close_code } " )
29+ await self .channel_layer .group_discard (
30+ self .room_group_name ,
31+ self .channel_name
32+ )
33+
34+ # This function receive messages from WebSocket.
35+ async def receive (self , text_data ):
36+ text_data_json = json .loads (text_data )
37+ message = text_data_json ['message' ]
38+
39+ # Create a new message object
40+ username = await self .save_message (self .user_id , self .room_name , message )
41+
42+ await self .channel_layer .group_send ( # sends message to all users in a channel group
43+ self .room_group_name ,
44+ {
45+ 'type' : 'chat_message' , # Calls chat_message()
46+ 'message' : message ,
47+ 'username' : username
48+ }
49+ )
50+
51+ async def chat_message (self , event ):
52+ await self .send (text_data = json .dumps ({
53+ 'message' : 'successful' ,
54+ 'body' : event ['message' ],
55+ 'username' : event ['username' ]
56+ }))
57+
58+ @sync_to_async
59+ def save_message (self , id , room_name , content ):
60+ try :
61+ user = User .objects .get (id = id )
62+ chat = Chat .objects .get (name = room_name )
63+ Message .objects .create (content = content , chat = chat , sender = user ) # Creates and saves message
64+ return user .username
65+ except (Chat .DoesNotExist ):
66+ print (f"Chat room '{ room_name } ' not found. Message not saved." )
67+ return "Unknown"
0 commit comments