Thanks for your time. I am just saying that I don’t really mean it will be in a rush. I already told the client, what the issue is and how long it might take to resolve it, so its not like am rushing anyone. Thanks in anticipation.
There are still too many gaps in the information provided here.
A lot of things can be going wrong if the structure and content of your production database doesn’t match exactly what you’re using in development. These differences would show up as errors in the logs or on the Daphne console.
My next recommendation would be then to stop the Daphne service and open up another shell session, running Daphne directly from the shell. Then connect to it to see what messages are being generated.
If this doesn’t yield useful information, then I’m back to suggesting that you add a lot of print statements into you consumer so that you can see what is being passed to, and returned from, every method call in your consumer.
Thank you very much for your time and patience. I tried your recommendations by adding a lot of print statements on consumers.py and also running daphne directly on my server terminal after stopping daphne. I was able to debug and get the issue. The issue was with the consumers.py.
Thanks it works fine now. Here is the updated code
consumers.py
from channels.generic.websocket import AsyncWebsocketConsumer, WebsocketConsumer
import json
from channels.db import database_sync_to_async
from urllib.parse import urljoin
from api.models import ChatMessage
from api.serializers import UserProfileSerializer
from django.contrib.auth import get_user_model
import pprint
User = get_user_model()
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.user = self.scope.get("user")
if not self.user.is_authenticated:
await self.close()
print("User not authenticated")
return
self.room_name = self.scope["url_route"]["kwargs"]["room_name"]
self.room_group_name = f"private_chat_{self.room_name}"
# Add user to the room group
await self.channel_layer.group_add(self.room_group_name, self.channel_name)
print("Add user to the room group")
# Retrieve and send unread messages for this user
unread_messages = await self.get_unread_messages(self.room_group_name)
print("Retrieve and send unread messages for this user")
# Determine the host to build absolute URLs
protocol = "https" if self.scope.get("scheme") == "https" else "http"
host = f"{protocol}://{self.scope['server'][0]}:{self.scope['server'][1]}"
print("Determine the host to build absolute URLs")
for message in unread_messages:
print("message loops")
profile_picture_url = None
if message["profile_picture"]:
profile_picture_url = urljoin(host, message["profile_picture"].url)
await self.channel_layer.group_send(
self.room_group_name,
{
"type": "private_chat_message",
"message": message["message"],
"username": message["sender_username"],
"timestamp": message["timestamp"].isoformat(),
"sender": {
"full_name": message["full_name"],
"type": message["type"],
"profile_picture": profile_picture_url,
},
},
)
print("group sent")
await self.accept()
print("User connected to the room:", self.room_name)
async def disconnect(self, close_code):
# Remove user from the room group
await self.channel_layer.group_discard(self.room_group_name, self.channel_name)
print("User disconnected from the room:", self.room_name)
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json.get("message")
recipient_username = text_data_json.get("recipient")
if recipient_username:
recipient_user = await self.get_user_by_username(recipient_username)
if recipient_user:
# Check if the user is part of this chat
# if not self.is_user_in_chat(recipient_user):
# print("User not authorized to join this chat")
# return
saved_message = await self.save_private_message(
self.user.id, recipient_user.id, message, self.room_group_name
)
protocol = "https" if self.scope.get("scheme") == "https" else "http"
host = f"{protocol}://{self.scope['server'][0]}:{self.scope['server'][1]}"
user_pic = saved_message.sender.profile_picture
# pprint(user_pic)
profile_picture_url = None
if user_pic != '':
profile_picture_url = urljoin(host, saved_message.sender.profile_picture.url)
data = {
"type": "private_chat_message",
"message": message,
"username": self.user.username,
"sender": {
"full_name": saved_message.sender.get_full_name(),
"type": saved_message.sender.type,
"profile_picture": profile_picture_url,
},
"timestamp": saved_message.timestamp.isoformat()
}
pprint.pprint(data)
await self.channel_layer.group_send(
self.room_group_name,
{
"type": "private_chat_message",
"message": message,
"username": self.user.username,
"sender": {
"full_name": saved_message.sender.get_full_name(),
"type": saved_message.sender.type,
"profile_picture": profile_picture_url,
},
"timestamp": saved_message.timestamp.isoformat()
},
)
print("channel layer group sent")
async def private_chat_message(self, event):
message = event["message"]
username = event["username"]
sender = event['sender']
timestamp = event["timestamp"]
await self.send(
text_data=json.dumps(
{
"message": message,
"username": username,
"timestamp": timestamp,
"sender": sender,
"type": "private_chat",
}
)
)
print("Private chat message sent")
@database_sync_to_async
def save_private_message(self, sender_id, recipient_id, message, group_name):
sender = User.objects.get(id=sender_id)
recipient = User.objects.get(id=recipient_id)
print("Chat message created")
return ChatMessage.objects.create(
sender=sender, recipient=recipient, message=message, group_name=group_name
)
@database_sync_to_async
def get_user_by_username(self, username):
print("Username was gotten")
try:
return User.objects.get(username=username)
except User.DoesNotExist:
return None
@database_sync_to_async
def get_unread_messages(self, group_name):
# Get all messages for the specified group
messages = ChatMessage.objects.filter(group_name=group_name)
# print(UserProfileSerializer(messages[0].sender).data)
print("Get unread messages")
return [
{
"message": message.message,
"sender_username": message.sender.username,
"timestamp": message.timestamp,
"full_name": message.sender.get_full_name(),
"type": message.sender.type,
"profile_picture": message.sender.profile_picture,
}
for message in messages
]
def is_user_in_chat(self, recipient_user):
# Check if the user and recipient are part of this chat room
users_in_chat = self.room_name.split("__")
print("Check is user in chat")
return (
self.user.username in users_in_chat
and recipient_user.username in users_in_chat
)
async def chat_message(self, event):
message = event["message"]
username = event["username"]
await self.send(
text_data=json.dumps(
{
"message": message,
"username": username,
}
)
)
self.send(
text_data=json.dumps(
{
"message": "message",
}
)
)
print("Chat message sent here")