215 lines
6.8 KiB
Python
215 lines
6.8 KiB
Python
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']
|
|
})) |