pythondjangowebsocket

How can I get the member list of log-in-ed


I am using the django and websocket.

I have the script like this, a user can login a websocket group

Now I want to return the list of users log-in-ed and return the list to the client.

How can I make this?

class ChatConsumer(AsyncWebsocketConsumer):

    async def connect(self):

        self.room_group_name = self.scope["url_route"]["kwargs"]["room_name"]

        logger.info("channel_name:{} / group_name {} / room_name {}".format(self.channel_name,self.room_group_name,self.scope["url_route"]["kwargs"]["room_name"]))
        await self.channel_layer.group_add(
           self.room_group_name,
           self.channel_name
        )
        await self.accept()
        await self.send(text_data=json.dumps({
            'channel_name': self.channel_name,
            'room_group_name':self.room_group_name,
            'member_list': 'how can I get the member??'
        }))

Solution

  • Currently there is no direct way from Django channel to do it, I suggest to you if you are working on production level to use Redis for example to store the data for some time without effect on app performance :

    Example :

    import aioredis
    sync def connect(self):
        self.room_group_name = self.scope["url_route"]["kwargs"]["room_name"]
        self.redis = await aioredis.create_redis_pool('redis://localhost')
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        await self.accept()
        
        # Add the channel to a Redis set
        await self.redis.sadd(self.room_group_name, self.channel_name)
        
        # Get updated member list
        members = await self.redis.smembers(self.room_group_name)
        members = list(m.decode('utf-8') for m in members)
        
        await self.send(text_data=json.dumps({
            'channel_name': self.channel_name,
            'room_group_name': self.room_group_name,
            'member_list': members
        }))
    

    and you must close the connection when you don't need it

    async def disconnect(self, close_code):
        await self.redis.srem(self.room_group_name, self.channel_name)
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )
        self.redis.close()
        await self.redis.wait_closed()
    

    Note: this solution have a good side and a bad side depends on your case Bad side: (Redis limitations) I really suggest to you to read more about Redis if you don't have enough knowledge about it