Article

Django Channels: Real-time Notifications

Last updated 
Apr 15, 2019
 min read

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.
1class User(AbstractBaseUser, PermissionsMixin):
2    """
3        Maintain user and its attributes
4    """
5
6    @property
7    def group_name(self):
8        """
9        Returns a group name based on the user's id to be used by Django Channels.
10        Example usage:
11        user = User.objects.get(pk=1)
12        group_name = user.group_name
13        """
14        return "user_%s" % self.id
  • 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

Authors

Sarang Patel

Software Engineer
I specialize in developing robust solutions and enjoy tackling complex problems while optimizing code. Passionate about continuous learning, I’m always looking for new challenges and ways to contribute to the tech community.

Tags

No items found.

Have a project in mind?

Read