Sending a message to a single user using django-channels Sending a message to a single user using django-channels django django

Sending a message to a single user using django-channels


Little update since Groups work differently with channels 2 than they did with channels 1. There is no Group class anymore, as mentioned here.

The new groups API is documented here. See also here.

What works for me is:

# Required for channel communicationfrom channels.layers import get_channel_layerfrom asgiref.sync import async_to_syncdef send_channel_message(group_name, message):    channel_layer = get_channel_layer()    async_to_sync(channel_layer.group_send)(        '{}'.format(group_name),        {            'type': 'channel_message',            'message': message        }    )

Do not forget to define a method to handle the message type in the Consumer!

    # Receive message from the group    def channel_message(self, event):        message = event['message']        # Send message to WebSocket        self.send(text_data=json.dumps({            'message': message        }))


Expanding on @Flip's answer of creating a group for that particular user.

In your python function in your ws_connect function you can add that user into a a group just for them:

consumers.py

from channels.auth import channel_session_user_from_httpfrom channels import Group@channel_session_user_from_httpdef ws_connect(message):    if user.is_authenticated:        Group("user-{}".format(user.id)).add(message.reply_channel)

To send that user a message from your python code:

my view.py

import jsonfrom channels import Groupdef foo(user):    if user.is_authenticated:        Group("user-{}".format(user.id)).send({            "text": json.dumps({            "foo": 'bar'        })    })

If they are connected they will receive the message. If the user is not connected to a websocket it will fail silently.

You will need to also ensure that you only connect one user to each user's Group, otherwise multiple users could receive a message that you intended for only a specific user.

Have a look at django channels examples, particularly multichat for how to implement routing, creating the websocket connection on the client side and setting up django_channels.

Make sure you also have a look at the django channels docs.


In Channels 2, you can save self.channel_name in a db on connect method that is a specific hash for each user. Documentation here

from asgiref.sync import async_to_syncfrom channels.generic.websocket import AsyncJsonWebsocketConsumerimport jsonclass Consumer(AsyncJsonWebsocketConsumer):    async def connect(self):        self.room_group_name = 'room'        if self.scope["user"].is_anonymous:            # Reject the connection            await self.close()        else:            # Accept the connection            await self.channel_layer.group_add(                self.room_group_name,                self.channel_name            )            await self.accept()        print( self.channel_name )

Last line returns something like specific.WxuYsxLK!owndoeYTkLBw

This specific hash you can save in user's table.