Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending a message to a single user using django-channels

I have been trying out django-channels including reading the docs and playing around with the examples.

I want to be able to send a message to a single user that is triggered by saving a new instance to a database.

My use case is creating a new notification (via a celery task) and once the notification has saved, sending this notification to a single user.

This sounds like it is possible (from the django-channels docs)

...the crucial part is that you can run code (and so send on channels) in response to any event - and that includes ones you create. You can trigger on model saves, on other incoming messages, or from code paths inside views and forms.

However reading the docs further and playing around with the django-channels examples, I can't see how I can do this. The databinding and liveblog examples demonstrate sending to a group, but I can't see how to just send to a single user.

like image 547
lukeaus Avatar asked Sep 04 '16 23:09

lukeaus


People also ask

How many connections can Django channels handle?

Websockets go into a server called Daphne (Daphne is a HTTP, HTTP2 and WebSocket protocol server for ASGI and ASGI-HTTP, developed to power Django Channels) can handle hundreds or potentially thousands of simultaneous connections open at once.

Does Django channels need Redis?

Django does not support Redis internally, so we need to use the extra package. We are going to use django-redis . It's full-featured Redis cache backend for Django. This will install a couple more dependencies, including redis-py — Python interface to the Redis.

Why we use Redis with Django channels?

The Redis layer is the recommended backend to run Channels with. It supports both high throughput on a single Redis server as well as the ability to run against a set of Redis servers in a sharded mode. It will be used automatically if it's installed.

What are consumers in Django channels?

Consumers are the counterpart to Django views. Any user connecting to our app will be added to the “users” group and will receive messages sent by the server. When the client disconnects from our app, the channel is removed from the group, and the user will stop receiving messages.


1 Answers

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 communication
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync


def 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
        }))
like image 65
user42488 Avatar answered Sep 22 '22 09:09

user42488