Django channels

I have few questions about Django Channels, WebSockets and chats. Google service leads me to chat rooms where people can connect and start chatting. But I do not know how one user can send another instant user message.

For instance:

1) I add John to my friends and want to start a chat. 2) On the server side, I can create a Room object, with me and John as members. 3) When I send a message via WebSocket to this room, I know who this message is for, but I do not know how to get John’s channel

@channel_session_user_from_http def ws_connect(message): rooms_with_user = Room.objects.filter(members=message.user) for r in rooms_with_user: Group('%s' % r.name).add(message.reply_channel) @channel_session_user def ws_receive(message): prefix, label = message['path'].strip('/').split('/') try: room = Room.objects.get(name=label) except Exception, e: room = Room.objects.create(name=get_random_string(30)) for u in message.chmembers: room.members.add(u) # here can be somethis like this # try reply_channel = Channels.objects.get(online=True, user=u) Group('%s' % r.name).add(reply_channel) Group('%s' % room.name).send({ "text": "%s : %s" % (message.user.username, message['text']), }) @channel_session_user def ws_disconnect(message): prefix, label = message['path'].strip('/').split('/') Group(label).discard(message.reply_channel) 
+5
source share
1 answer

Just make "automatic unique rooms" for pairs of users. The rest remains unchanged. For example, for example

 def get_group_name(user1, user2): return 'chat-{}-{}'.format(*sorted([user1.id, user2.id])) 

Give it two user objects, and it returns a unique room for this pair of users, ordered User.id , something like "chat-1-2" for users with User.id "1" and "2" ,.

Thus, a user can connect to several connected devices and receive messages sent between two users.

You can get the authenticated user object from message.user .

For the receiving User object, I just sent username along with the message. Then you can unpack it from message['text'] just like you unpack the actual message.

 payload = json.loads(message.content['text']) msg = payload['msg'] sender = message.user receiver = get_object_or_404(User, username=payload['receiver']) # ... here you could check if they have required permission ... group_name = get_group_name(sender, receiver) response = {'msg': msg} Group(group_name).send({'text': json.dumps(response)}) # ... here you could persist the message in a database ... 

Thus, you can remove all the β€œrooms” from your example, including the room table, etc. Because group names are always created on the fly when a message is sent between two users.


Another important thing: one user will connect later than another user and may skip the original messages. Therefore, when you connect, you probably want to check the chat_messages database table, get the last 10 or 20 messages between a pair of users, and send them back. In this way, users can catch up with their past conversation.

+6
source

All Articles