Reputation: 129
I have a couple of Django Channels groups that I use to send various messages to the client with.
Can I remove a specific user from one of these groups, using only the ID of the user that I want to remove?
Another potential option would be to force disconnect the user's connection using just their ID.
Upvotes: 3
Views: 2384
Reputation: 1214
First, you have to save the user's channel_name to their model
and we assume that you had the group_name of channels too
then you can use group_discard for deleting user from group like this:
group_name = 'name_of_channels_group'
user = User.objects.get(id=id)
channel_name = user.channel_name
async_to_sync(self.channel_layer.group_discard)(group_name, channel_name)
https://channels.readthedocs.io/en/stable/topics/channel_layers.html?highlight=group_send#groups
Upvotes: 4
Reputation: 2671
I have thought couple a days about this problem and have an idea how this can be implemented, but can't test it currently. You should try to change your receive() method
like this:
async def receive(self, text_data=None, bytes_data=None):
text_data_json = json.loads(text_data)
message = text_data_json['message']
users_to_kick = text_data_json['kick']
# you should inspect scope['user'] cuz I am not sure in what place
# user's id is placed, but there is 'user' object.
if self.scope['user']['id'] in list(map(int, users_to_kick)):
await self.close()
else:
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'some_method',
'message': message
}
)
You have to have Authorisation system enabled, you can't kick Anonymous users. And you have to send from Front-End a list of users which you want to kick.
Upvotes: 0
Reputation: 129
I solved this in the end by storing each channel name (self.channel_name) on channel connection, and removing them on disconnect. These are then tied to a Django user object.
Now, if I want to remove a user from a group, I can just loop over all stored channel names tied to a user object, and run group_discard.
Upvotes: -1
Reputation: 694
You need to prevent connect based on scope['user']
in consumer connect
method like this:
class MyConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
id_cannot_connect = 1
if self.scope['user'] == id_cannot_connect:
await self.close()
else:
await self.accept()
If you want to make lists of users allowed to connect to specific groups you'll need to store groups and group users in your database and use it the same way in connect
method like above.
edit: You can discard user's channel from the group with group_discard in receive_json
where you still have access to self.scope['user']
to filter needed users.
Upvotes: -1