Search code examples
pythondjangodjango-channelsdjango-signals

Channels - how do I send data through websocket when signal is received?


I want to stream data from a database through websocket. Basically a new record is being inserted into DataModel at every second and I want to send this new record through websocket as soon as it's inserted. Someone recommended me to use signal when the model's save() method is called. So to my models.py I just added this:

def save_post(sender, instance, **kwargs):
    print('signal')
post_save.connect(save_post, sender=DataModel)

What to I put inside of save_post and also on my consumers.py so that the data goes through?


Solution

  • You will first have to connect to your django channel layer using following code:

    from channels.layers import get_channel_layer
    from asgiref.sync import async_to_sync
    channel_layer = get_channel_layer()
    data = <your-data> # data you want to send
    async_to_sync(channel_layer.group_send(<group_name>, {
        "type": "notify",
        "message": data
    }))
    

    It will connect you to your default backend layer you defined in settings file:

    CHANNEL_LAYERS = {
        "default": {
            "BACKEND": "channels_redis.core.RedisChannelLayer",
            "CONFIG": {
                "hosts": [("localhost", 6379)],
            },
        },
    }
    

    and will call a function named notify(name of function is your choice) in your Consumer class for all the users that have the group <group_name>

    async def notify(self, event):
        data = event["message"]
        # here you can do whatever you want to do with data
    

    For more information you can have working example here: https://channels.readthedocs.io/en/latest/tutorial/part_2.html#enable-a-channel-layer