diff --git a/app/signalr/hub/hub.py b/app/signalr/hub/hub.py index 92fc90d..3c8fe98 100644 --- a/app/signalr/hub/hub.py +++ b/app/signalr/hub/hub.py @@ -99,6 +99,16 @@ class Hub[TState: UserState]: return client return default + def get_before_clients(self, id: str, current_token: str) -> list[Client]: + clients = [] + for client in self.clients.values(): + if client.connection_id != id: + continue + if client.connection_token == current_token: + continue + clients.append(client) + return clients + @abstractmethod def create_state(self, client: Client) -> TState: raise NotImplementedError @@ -117,6 +127,11 @@ class Hub[TState: UserState]: if group_id in self.groups: self.groups[group_id].discard(client) + async def kick_client(self, client: Client) -> None: + await self.call_noblock(client, "DisconnectRequested") + await client.send_packet(ClosePacket(allow_reconnect=False)) + await client.connection.close(code=1000, reason="Disconnected by server") + async def add_client( self, connection_id: str, diff --git a/app/signalr/router.py b/app/signalr/router.py index 053117c..1b50fcf 100644 --- a/app/signalr/router.py +++ b/app/signalr/router.py @@ -98,6 +98,11 @@ async def connect( if error or not client: await websocket.close(code=1008) return + + connected_clients = hub_.get_before_clients(user_id, id) + for connected_client in connected_clients: + await hub_.kick_client(connected_client) + await hub_.clean_state(client, False) task = asyncio.create_task(hub_.on_connect(client)) hub_.tasks.add(task)