Channels : how to list sockets connected to a group ?

Can I get a list of connected sockets for a group, that I can use in a consumer ?

My use case : I built a chat app that only allows for two users chat. I’m creating notifications for messages sent, but I don’t want to create a notification if the recipient is currently watching the conversation.

My first thought was to look for a list of connected sockets in the conversation group. I’m creating the notification in a consumer, so if I could know which sockets are currently connected, I could make it work.

I found this 8 years old issue : https://github.com/django/channels/issues/293 , but since it’s based on Channels 2.0, I thought I’d ask again.

What is the proper way to do that ?

Nope. Quoting directly from Groups

They do not allow you to enumerate or list the channels in a group; it’s a pure broadcast system. If you need more precise control or need to know who is connected, you should build your own system or use a suitable third-party one.

I currently use django-channels-presence to provide this functionality - there are other ways to do it as well.

Note: This is tough. There are a number of edge cases where a user will remain being shown as present in a room after being disconnected because the server hasn’t yet caught up with that fact. So there’s a timing issue / race condition that you need to be aware of. (You need to decide just how critical this is for those marginal situations.)

2 Likes

I was going to say that Redis sets might be a way… I’d forgotten about this app.

Thanks for your replies. I can’t use this app because I’m using a custom User model, and it just don’t work.

But now I know how hard this notification system is, and I’m going to change the spec to simplify it. I can do that, it’s a personal project, and it feels like it’s the reasonable thing to do.

Thanks again.

Please clarify. I don’t see anything in the code that would prevent it from working with a custom user model.

Since the models are designed to work with custom users, I think that if it doesn’t work, the maintainer of the project would be interested in knowing that.

1 Like

Sure. We don’t mean the same thing with “custom User”. I didn’t follow the usual process for custom users. I’m building a proof of concept chat app, with no User connection or any User managment.

So I created a ChatUser model with two fields, I’m using the session to fake the authentication process. It don’t inherit the classic User model in any way. So when I tried to use the app you recommend, I got this :

  File ".../lib/python3.10/site-packages/channels_presence/models.py", line 47, in add
    room.add_presence(user_channel_name, user)
  File ".../lib/python3.10/site-packages/channels_presence/models.py", line 76, in add_presence
    if user and user.is_authenticated:
AttributeError: 'ChatUser' object has no attribute 'is_authenticated'

I’m almost done with this small project, and I will not add the Django User model just for a small notification feature. I guess this app is working with real custom users, but to be honest I don’t know :slight_smile:

Can you expand on that?

Is this entire Django/Channels implementation part of an existing project with an authentication process, or is it something separate and independent?

If the latter, you could still set settings.AUTH_USER_MODEL to your ChatUser model.

If it is part of a regular Django project, you could still fork the project and make the (one-line) change necessary to make it work in your system. That’s still a lot easier than building a complete library yourself.