i create object in AuthMiddlewareStack
class TokenAuthMiddleware:
handler: MessengerHandler = None
def __init__(self, inner):
self.inner = inner
async def generate_object(self):
if self.handler is None: # just for first time
self.handler= MessengerHandler()
await self.handler.import_key()
return self.handler
async def __call__(self, scope, send, rec):
model = await self.generate_object()
scope["handler"] = model
return await self.inner(scope, send, rec)
in AsyncWebsocketConsumer
class
@property
def _get_handler(self) -> MessengerHandler:
return self.scope["handler"]
connect
self._get_handler.add_new_channel(self.channel_name, self.user_api.user_id)
disconnect
async def disconnect(self, close_code):
if self.user_api.is_active:
self._get_handler.remove_channel(self.channel_name, self.user_api.user_id)
pass
MessengerHandler
class MessengerHandler:
channels: dict[int, ClientChannels] = {}
def add_new_channel(self, channel: str, user_id: int):
....
def remove_channel(self, channel: str, user_id: int):
....
def get_user_channels(self, user_id: int, without_channel: str = None) -> list:
...
otherwise safe thread
using Django-Redis package
handle channels
@staticmethod
def add_new_channel(channel: str, user_id: int, client_type: str, client_id: int):
channel_name = f"u_{user_id}_{client_type}_{client_id}"
cache.set(channel_name, channel, timeout=None)
@staticmethod
def remove_channel(channel_type: str, user_id: int, client_id: int):
channel_name = f"u_{user_id}_{channel_type}_{client_id}"
cache.delete(channel_name)
@staticmethod
def get_user_channels(user_id: int) -> list:
channel_name = f"u_{user_id}_*"
values = cache.get_many(cache.keys(channel_name))
return [v for k, v in values.items()]