Skip to content

Commit

Permalink
real time chat[]
Browse files Browse the repository at this point in the history
start to pulling chats in real time. not working yet
  • Loading branch information
Taseen18 committed Mar 30, 2024
1 parent f48f0f8 commit 6ec467f
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 22 deletions.
Binary file modified backend/chat/__pycache__/consumers.cpython-311.pyc
Binary file not shown.
Binary file modified backend/chat/__pycache__/routing.cpython-311.pyc
Binary file not shown.
Binary file modified backend/chat/__pycache__/signals.cpython-311.pyc
Binary file not shown.
80 changes: 64 additions & 16 deletions backend/chat/consumers.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,56 @@
from channels.generic.websocket import AsyncWebsocketConsumer
import json
from .models import Message
from .models import Message, Chat
from django.db.models import Q
from asgiref.sync import sync_to_async

class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = f'chat_{self.room_name}'

# Join room group
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
self.user = self.scope["user"]
self.room_name = self.scope['url_route'].get('kwargs', {}).get('room_name')

if self.room_name:
self.room_group_name = f'chat_{self.room_name}'
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
else:
self.chat_group_name = f'user_{self.user.id}_chats'
await self.channel_layer.group_add(
self.chat_group_name,
self.channel_name
)


await self.accept()
print("webhook accepted")
print("WebSocket accepted")

recent_messages = await fetch_recent_messages(self.room_name)
for message in recent_messages:
await self.send_chat_message(message)


async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
# Conditionally leave the appropriate group
if self.room_name:
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
else:
await self.channel_layer.group_discard(
self.chat_group_name,
self.channel_name
)

# Receive message from WebSocket (not used here but included for completeness)
async def receive(self, text_data):
pass
text_data_json = json.loads(text_data)
message_type = text_data_json.get('type')

if message_type == 'fetch_chats':
await self.fetch_and_send_chats()

async def chat_message(self, event):
await self.send(text_data=json.dumps({
Expand All @@ -46,6 +64,22 @@ async def send_chat_message(self, message):
'message': message
}))

async def chat_update(self, event):
# Handle incoming chat update messages
# For simplicity, we're just directly forwarding the update
await self.send(text_data=json.dumps({
'type': 'chat_update',
'data': event['data']
}))

async def fetch_and_send_chats(self):
# Fetch chat list for the user and send it
chats = await get_user_chats(self.user.id)
await self.send(text_data=json.dumps({
'type': 'chat_list',
'chats': chats
}))

@sync_to_async
def fetch_recent_messages(room_name, limit=10):
print("Connecting to room:", room_name)
Expand All @@ -59,3 +93,17 @@ def fetch_recent_messages(room_name, limit=10):
print("Fetched messages:", recent_messages) # Debug print
return recent_messages

@sync_to_async
def get_user_chats(user_id):
chats = Chat.objects.filter(
Q(employee_id=user_id) | Q(mhp_id=user_id)
).order_by('-last_message_at')

recent_chats = [{
'chat_id': chat.id,
'last_message_at': chat.last_message_at.strftime("%Y-%m-%d %H:%M:%S"),
'employee_id': chat.employee_id,
'mhp_id': chat.mhp_id,
} for chat in chats]
print("Fetched chats:", recent_chats)
return recent_chats
1 change: 1 addition & 0 deletions backend/chat/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
from . import consumers

websocket_urlpatterns = [
path('ws/chat/', consumers.ChatConsumer.as_asgi()),
path('ws/chat/<str:room_name>/', consumers.ChatConsumer.as_asgi()),
]
24 changes: 22 additions & 2 deletions backend/chat/signals.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.db.models.signals import post_save
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from .models import Message
from .models import Message, Chat
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync

Expand All @@ -27,3 +27,23 @@ def send_message_update(sender, instance, created, **kwargs):
message_content
)

@receiver(post_save, sender=Chat)
@receiver(post_delete, sender=Chat) # If you want to handle deletions
def send_chat_update(sender, instance, **kwargs):
channel_layer = get_channel_layer()
group_name = "chats_group" # This could be a general group name if broadcasting to all users

chat_content = {
'type': 'chat_update', # Corresponds to the method in the consumer
'chat': {
'id': instance.id,
'last_updated_at': instance.last_updated_at.strftime("%Y-%m-%d %H:%M:%S"),
'employee_id': instance.employee_id,
'mhp_id': instance.mhp_id,
}
}

async_to_sync(channel_layer.group_send)(
group_name,
chat_content
)
Binary file modified backend/dump.rdb
Binary file not shown.
32 changes: 28 additions & 4 deletions web/src/pages/Messenger.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function Messenger() {
const webSocket = useRef(null);

useEffect(() => {
/*
const fetchChats = async () => {
if (!token || !token.session.access_token) {
console.error('Token not available');
Expand All @@ -34,12 +35,35 @@ function Messenger() {
};
fetchChats();
*/

const chatsWsScheme = window.location.protocol === "https:" ? "wss" : "ws";
const chatsWsUrl = `${chatsWsScheme}://localhost:8000/ws/chat/`;

const chatsWebSocket = new WebSocket(chatsWsUrl);

chatsWebSocket.open = (event) => {
console.log('Chats WebSocket opened');
};

chatsWebSocket.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("Chat update received:", data);
setChats(data.chats);
};

chatsWebSocket.onclose = (event) => {
console.log('Chats WebSocket closed');
};

chatsWebSocket.onerror = (event) => {
console.log('Chats WebSocket error', event);
};

return () => {
if (webSocket.current) {
webSocket.current.close();
}
chatsWebSocket.close();
};
}, [token]);
}, []);

useEffect(() => {
if (selectedChatId) {
Expand Down

0 comments on commit 6ec467f

Please sign in to comment.