128 lines
4.6 KiB
Python
128 lines
4.6 KiB
Python
from channels.generic.websocket import AsyncWebsocketConsumer, WebsocketConsumer
|
|
import json
|
|
import django
|
|
django.setup()
|
|
|
|
from accounts.models import IAmPrincipal
|
|
from channels.exceptions import StopConsumer
|
|
from asgiref.sync import async_to_sync, sync_to_async
|
|
from django.utils import timezone
|
|
from chat.models import ChatGroup, ChatMessage
|
|
from channels.db import database_sync_to_async
|
|
from django.db import close_old_connections
|
|
from rest_framework_simplejwt.tokens import AccessToken
|
|
from rest_framework_simplejwt.authentication import JWTAuthentication
|
|
import threading
|
|
|
|
|
|
class ChatConsumer(AsyncWebsocketConsumer):
|
|
async def connect(self):
|
|
print("self.scope: ", self.scope)
|
|
self.room_name = (
|
|
self.scope.get("url_route", {}).get("kwargs", {}).get("room_name")
|
|
)
|
|
print("self.room_name: ", self.room_name)
|
|
token_key = self.scope["url_route"]["kwargs"]["token"]
|
|
print("token_key: ", token_key)
|
|
self.user = await self.get_user_async(token_key)
|
|
print("self.user: ", self.user)
|
|
# Start the thread to get the user object
|
|
# user_thread = threading.Thread(target=self.get_user_async, args=(token_key,))
|
|
# user_thread.start()
|
|
|
|
# # Wait for the thread to finish and assign the user object to the scope
|
|
# user_thread.join()
|
|
# self.scope["user"] = self.user
|
|
# print("User: ", self.scope["user"])
|
|
# print("self.user: ", self.user)
|
|
|
|
# Join room group
|
|
await self.channel_layer.group_add(self.room_name, self.channel_name)
|
|
print("Time: ", timezone.now())
|
|
await self.accept()
|
|
|
|
async def disconnect(self, close_code):
|
|
# Leave room group
|
|
print("Time: ", timezone.now())
|
|
await self.channel_layer.group_discard(self.room_name, self.channel_name)
|
|
raise StopConsumer()
|
|
# await self.disconnect(close_code)
|
|
|
|
# Receive message from WebSocket
|
|
async def receive(self, text_data):
|
|
print("text_data: ", text_data)
|
|
print("self.user: ", self.user)
|
|
try:
|
|
text_data_json = json.loads(text_data)
|
|
message = text_data_json["message"]
|
|
except json.JSONDecodeError:
|
|
# Handle non-JSON message
|
|
message = text_data
|
|
print("message: ", message)
|
|
group = await self.get_chat_group(self.room_name)
|
|
print("group: ", group)
|
|
await self.create_chat_message(group, message, self.user)
|
|
# await self.create_chat_message(group, text_data_json, user)
|
|
|
|
# Send message to room group
|
|
await self.channel_layer.group_send(
|
|
# self.room_name, {"type": "chat.message", "message": message}
|
|
self.room_name,
|
|
{
|
|
"type": "chat.message",
|
|
"message": message,
|
|
"timestamp": str(timezone.now()),
|
|
"user": self.user.email,
|
|
"first_name": self.user.first_name,
|
|
"profile_photo": self.user.profile_photo.url
|
|
if self.user.profile_photo and self.user.profile_photo.url
|
|
else None,
|
|
},
|
|
)
|
|
|
|
@database_sync_to_async
|
|
def create_chat_message(self, room_name, message, user):
|
|
# principal = IAmPrincipal.objects.get(id=self.user)
|
|
return ChatMessage.objects.create(
|
|
group=room_name,
|
|
timestamp=timezone.now(),
|
|
message=message,
|
|
user=self.user,
|
|
)
|
|
|
|
@database_sync_to_async
|
|
def get_chat_group(self, room_name):
|
|
return ChatGroup.objects.filter(name=room_name).first()
|
|
|
|
# Receive message from room group
|
|
async def chat_message(self, event):
|
|
print("event: ", event)
|
|
message = event["message"]
|
|
user = event["user"]
|
|
first_name = event["first_name"]
|
|
profile_photo = event["profile_photo"]
|
|
timestamp = event["timestamp"]
|
|
# new_message = str(user) + " :- " + message
|
|
# Send message to WebSocket
|
|
await self.send(
|
|
text_data=json.dumps(
|
|
{
|
|
"message": message,
|
|
"user": user,
|
|
"first_name": first_name,
|
|
"profile_photo": profile_photo,
|
|
"timestamp": timestamp,
|
|
}
|
|
)
|
|
)
|
|
|
|
@database_sync_to_async
|
|
def get_user_async(self, token):
|
|
try:
|
|
decoded_token = JWTAuthentication().get_validated_token(token)
|
|
user = JWTAuthentication().get_user(decoded_token)
|
|
self.user = user
|
|
return user
|
|
except Exception as e:
|
|
self.user = None
|