Featured Image
Software Development

Django Channels: Real-time Notifications

Whenever you hear the word real-time, the first thing that crosses your mind(If you are a developer) is a Web Socket Connection.
Django doesn’t support web sockets and this is where Django-Channels comes to my rescue.
Below content is for Django-channels version 2.x and Python version 3.x.

What I implemented using Channels?

  • The task is to generate notifications and send them in real-time using sockets.
  • To reduce complexity, we’ll consider a single user scenario. Suppose a particular notification is to be sent to user X, the main challenge is to identify the number of places from where user X is logged in and then send this notification to all of them.
  • For this, I use the concept called Group in Django-channels and I am able to send the notification to all the places without actually knowing the number of places from where X is logged in. Let’s see what is a Group in Django-Channels.

What are groups in Django-Channels?

  • A group is a collection of socket connections.
  • Each group is identified by a unique name.
  • Channels identify a socket connection by providing a unique key to it.
  • So when you add a connection to a group, the key of that connection is stored in the group.
  • Hence a Group holds all the keys of different socket connections.
  • A single socket connection can be added to multiple groups.
  • The benefit of a group is that you can broadcast a message to all the connections of a group at once.
  • In order to add a connection to group use the group_add method of channel_layer and in order to remove a connection from group use the group_discard method of the channel layer.
  • You can broadcast a message to channels in the group using group_send method of the channel layer.
  • If you want to know more about, what is channel layer, check here.

How I designed the groups for individual users?

  • Whenever a user logs in to my platform, I use Reconnecting WebSocket to open a new socket connection to Django-channels.
  • I pass the user authentication token while making a socket connection and in backend use this token to identify the user.
  • I have also added a property on my User model to generate a group name for each user. Below is the code for it
  • Now, whenever a new socket connection is made using ReconnectingWebSocket, channels call the connect method of my consumer. Learn more about Consumers here.
  • In this connect method, I determine the user, get the group name for that user and finally add the new connection to that group by using the group_add method. For code, see the snippet at the end.
  • Now recalling the scenario, if I am to send a notification to a particular user X and X is logged in from 5 tabs, I just need to broadcast it in the group and Django-channels do the needful to send it to all the tabs.
  • You might be wondering, how to discard the channel from the group whenever the user closes a tab or logs out. So whenever a user closes a tab socket is automatically disconnected for that tab and if the user logs out, I have explicitly written code that disconnects the active socket connection.
  • Whenever a connection closes, Django-channels call the disconnect method of the consumer.
  • Within this disconnect method, I use the group_discard method to remove the connection from the group. See below snippet for the code.

So by using Django-Channels, I am able to complete my task of sending the notifications in Real-time.
I have also used Channels to create a real-time messaging app and it’s working seamlessly.

Hope you enjoyed the article. Cheers!

 Also read: Getting Started with Two-Factor Authentication in Django Admin Panel

author
Sarang Patel