import json from channels.generic.websocket import AsyncWebsocketConsumer from channels.db import database_sync_to_async from datetime import datetime from django.utils import timezone import uuid from .models import AnonMessage class AnonymChatConsumer(AsyncWebsocketConsumer): async def connect(self): # Generate a unique user ID for this WebSocket connection self.user_id = str(uuid.uuid4()) self.room_name = "global_room" # Add the user to the global room group await self.channel_layer.group_add(self.room_name, self.channel_name) # Accept the WebSocket connection await self.accept() async def disconnect(self, code): # Remove the user from the global room group when disconnected await self.channel_layer.group_discard(self.room_name, self.channel_name) await self.close(code) async def receive(self, text_data): # Parse the received JSON message data_json = json.loads(text_data) # Include the user ID and time for broadcasting event = { "type": "send_message", "message": data_json["message"], "user_id": self.user_id, # Attach the user ID to the event } # Broadcast the message to the global room group await self.channel_layer.group_send(self.room_name, event) async def send_message(self, event): # Check if the sender's ID is the same as the current user to avoid sending back the message message_time = await self.create_message(event["message"]) print({"time": message_time.strftime("%b. %d, %Y, %I:%M %p").lower()}) if event["user_id"] != self.user_id: # Format the message with time and send to WebSocket clients response = { "message": event["message"], "time": message_time.strftime("%b. %d, %Y, %H:%M") } await self.send(text_data=json.dumps(response)) @database_sync_to_async def create_message(self, text): # Create a new message in the database and return its timestamp return AnonMessage.objects.create(text=text).time user_counter = 0 peers = {} class AnonymVoiceConsumer(AsyncWebsocketConsumer): async def connect(self): self.group_name = 'voice_room_group' self.peer_id = None await self.channel_layer.group_add( self.group_name, self.channel_name ) await self.accept() async def disconnect(self, close_code): global user_counter, peers await self.channel_layer.group_discard( self.group_name, self.channel_name ) if self.peer_id in peers: del peers[self.peer_id] user_counter -= 1 await self.send_user_count() async def receive(self, text_data): global user_counter, peers data_json = json.loads(text_data) if data_json['type'] == "connected_user": self.peer_id = data_json['peer_id'] peers[self.peer_id] = self.channel_name user_counter += 1 await self.send_user_count() await self.send_peer_id_to_others(self.peer_id) elif data_json['type'] == "disconnecting_user": if self.peer_id in peers: del peers[self.peer_id] user_counter -= 1 await self.send_user_count() elif data_json['type'] == "request_user_count": await self.send_user_count() async def send_user_count(self): await self.channel_layer.group_send( self.group_name, { 'type': 'group_announcement', 'users_count': user_counter, } ) async def send_peer_id_to_others(self, peer_id): await self.channel_layer.group_send( self.group_name, { 'type': 'peer_id_message', 'peer_id': peer_id, 'exclude': self.channel_name # Exclude the sender } ) async def group_announcement(self, event): users_count = event['users_count'] await self.send(text_data=json.dumps({ 'type': 'user_count_message', 'users_count': users_count })) async def peer_id_message(self, event): if self.channel_name != event.get('exclude'): await self.send(text_data=json.dumps({ 'type': 'peer_id_message', 'peer_id': event['peer_id'] })) class DirectVoiceConsumer(AsyncWebsocketConsumer): async def connect(self): self.group_name = "id_pool" self.peer_id = None await self.channel_layer.group_add( self.group_name, self.channel_name ) await self.accept() async def disconnect(self, close_code): global user_counter, peers await self.channel_layer.group_discard( self.group_name, self.channel_name ) if self.peer_id in peers: del peers[self.peer_id] user_counter -= 1 await self.send_user_count() async def receive(self, text_data): global user_counter, peers data_json = json.loads(text_data) if data_json['type'] == "connected_user": self.peer_id = data_json['peer_id'] peers[self.peer_id] = self.channel_name user_counter += 1 await self.send_user_count() await self.send_peer_id_to_others(self.peer_id) elif data_json['type'] == "disconnecting_user": if self.peer_id in peers: del peers[self.peer_id] user_counter -= 1 await self.send_user_count() elif data_json['type'] == "request_user_count": await self.send_user_count() async def send_user_count(self): await self.channel_layer.group_send( self.group_name, { 'type': 'group_announcement', 'users_count': user_counter, } ) async def send_peer_id_to_others(self, peer_id): await self.channel_layer.group_send( self.group_name, { 'type': 'peer_id_message', 'peer_id': peer_id, 'exclude': self.channel_name # Exclude the sender } ) async def group_announcement(self, event): users_count = event['users_count'] await self.send(text_data=json.dumps({ 'type': 'user_count_message', 'users_count': users_count })) async def peer_id_message(self, event): if self.channel_name != event.get('exclude'): await self.send(text_data=json.dumps({ 'type': 'peer_id_message', 'peer_id': event['peer_id'] }))