Reputation: 3424
I am working on a chat app that has Rooms. Each room has two users. A user can be in multiple rooms i.e, a user has multiple rooms. And now he is chatting in one room. But he receives a message in another room. I would like to notify about the message from other room to the user. How should I implement this?
Currently a websocket connection is established as: ws://localhost:8000/chat/int<room_id>/
And the group_name is named as "room"+room_id
. and So far I have:
async def connect(self):
room_id = self.scope['url_route']['kwargs']['room_id']
await self.channel_layer.group_add(
"room"+room_id,
self.channel_name
)
await self.accept()
async def receive(self, text_data):
await self.channel_layer.group_send(
self.room_name,
{
'type': 'chat_message',
'message': json.loads(text_data)
}
)
async def chat_message(self, event):
await self.send(text_data=json.dumps({
'message': event['message']
}))
Django 2.x django-channels 2.x python 3.6
Upvotes: 2
Views: 4084
Reputation: 1
django code for circulars and notifications system using class based and using serializer function with hole project code in step by step
Upvotes: -2
Reputation: 178
(idea:)I opened two sockets:
then on every message received from any user in the first explained channel(above), I will send proper reply to both of the sockets.
example at here: chatroom.subtionary.com (just click on one chatroom and enter with email) it also reorder the chat rooms list and pulse the element and also write the last message of each chatroom under its element, also enjoy reply and delete options!!
(I know this is the laziest way, but works well)
Upvotes: 0
Reputation: 6107
You need at least two models Message
, MessageThread
. When the user connects to the socket the channel is added to each thread group that the user is included in. You also have to add the channel_name to the user session.
messaging/models.py
class MessageThread(models.Model):
title = models.CharField()
clients = models.ManyToManyField(User, blank=True)
class Message(models.Model):
date = models.DateField()
text = models.CharField()
thread = models.ForeignKey('messaging.MessageThread', on_delete=models.CASCADE)
sender = models.ForeignKey(User, on_delete=models.SET_NULL)
chat/consumers.py
class ChatConsumer(WebSocketConsumer):
def connect(self):
if self.scope['user'].is_authenticated:
self.accept()
# add connection to existing groups
for thread in MessageThread.objects.filter(clients=self.scope['user']).values('id'):
async_to_sync(self.channel_layer.group_add)(thread.id, self.channel_name)
# store client channel name in the user session
self.scope['session']['channel_name'] = self.channel_name
self.scope['session'].save()
def disconnect(self, close_code):
# remove channel name from session
if self.scope['user'].is_authenticated:
if 'channel_name' in self.scope['session']:
del self.scope['session']['channel_name']
self.scope['session'].save()
async_to_sync(self.channel_layer.group_discard)(self.scope['user'].id, self.channel_name)
Upvotes: 1
Reputation: 523
I do something similar, you can try something like this:
connect(message):
// however you get your chatroom value from the socket
Group("%s" % chatroom).add(message.reply_channel)
message(message):
message = json.loads(message.content['text'])
chatroom = message['chatroom']
Group("%s" % chatroom).send({
"text": json.dumps({
"id": "newuser",
"username": message['username'],
"message": message['message']
})
})
I might have misread your question. Maybe something more like:
Create a unique id for each user and use that value as the 'chatroom', then send each message with a chatroom number and the user number that it should go to. Django can interpret the user id and sent the message to the right channel, then have the Javascript interpret it the message and roomnumber to bring them to the right page?
That is an interesting idea
Upvotes: 0