1
+ import json
2
+
3
+ from asgiref .sync import async_to_sync
4
+ from channels .generic .websocket import WebsocketConsumer
5
+ from pydantic import BaseModel
6
+ from .models import ChatMessage
7
+
8
+ class MessagePayload (BaseModel ):
9
+ user : str = "Anonymous"
10
+ message : str
11
+ timestamp : float = None
12
+
13
+ class GroupPayload (BaseModel ):
14
+ type : str
15
+ user : str = "Anonymous"
16
+ message : str
17
+ timestamp : float = None
18
+
19
+ class ChatConsumer (WebsocketConsumer ):
20
+ def connect (self ):
21
+ self .room_name = self .scope ["url_route" ]["kwargs" ]["room_name" ]
22
+ self .room_group_name = f"chat_{ self .room_name } "
23
+ # Join room group
24
+ async_to_sync (self .channel_layer .group_add )(
25
+ self .room_group_name , self .channel_name
26
+ )
27
+ self .accept ()
28
+
29
+ def disconnect (self , close_code ):
30
+ # Leave room group
31
+ async_to_sync (self .channel_layer .group_discard )(
32
+ self .room_group_name , self .channel_name
33
+ )
34
+
35
+ # Receive message from WebSocket
36
+ def receive (self , text_data ):
37
+ text_data_json = json .loads (text_data )
38
+ payload = MessagePayload (** text_data_json )
39
+ message = payload .message
40
+
41
+ persisted = ChatMessage .objects .create (
42
+ user = payload .user ,
43
+ message = message ,
44
+ room = self .room_name ,
45
+ )
46
+
47
+ group_payload = GroupPayload (
48
+ type = "chat_message" ,
49
+ message = message ,
50
+ user = payload .user ,
51
+ timestamp = int (persisted .timestamp .timestamp () * 1000 )
52
+ )
53
+
54
+ # Send message to room group
55
+ async_to_sync (self .channel_layer .group_send )(
56
+ self .room_group_name , group_payload .model_dump ()
57
+ )
58
+
59
+ # Receive message from room group
60
+ def chat_message (self , event ):
61
+ payload = GroupPayload (** event )
62
+ message_payload = MessagePayload (
63
+ user = payload .user ,
64
+ message = payload .message ,
65
+ timestamp = payload .timestamp ,
66
+ )
67
+
68
+ # Send message to WebSocket
69
+ self .send (text_data = message_payload .model_dump_json ())
0 commit comments