diff --git a/src/judas_server/backend/handler/hello_handler.py b/src/judas_server/backend/handler/hello_handler.py new file mode 100644 index 0000000..c2458a5 --- /dev/null +++ b/src/judas_server/backend/handler/hello_handler.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +from __future__ import annotations + +from typing import TYPE_CHECKING, override + +from judas_protocol import Category, ControlAction, Message + +from judas_server.backend.client import ClientStatus +from judas_server.backend.handler import BaseHandler + +if TYPE_CHECKING: + from judas_server.backend.backend_server import BackendServer + from judas_server.backend.client import Client + + +class HelloHandler(BaseHandler): + def __init__(self, backend_server: BackendServer) -> None: + super().__init__(backend_server) + + @override + def handle(self, client: Client, message: Message) -> None: + if client.id is not None: + return + + if ( + message.category != Category.CONTROL + or message.action != ControlAction.HELLO + ): + self.logger.error( + f"Expected HELLO message from {client}, got {message}, disconnecting client..." + ) + self.backend_server._disconnect(client) + return + + if message.payload.get("id") is None: + self.logger.error( + f"HELLO message from {client} missing 'id' field, disconnecting client..." + ) + self.backend_server._disconnect(client) + return + + client.id = message.payload["id"] + + # check if client already connected, if so disconnect old client and register new one + if ( + client.id in self.backend_server.clients + and self.backend_server.clients[client.id].status == "connected" + ): + old_client: Client = self.backend_server.clients[client.id] + self.backend_server.logger.warning( + f"Client {client.id} is already connected from {old_client.addr}, disconnecting old client..." + ) + self.backend_server.send_close(old_client) + return + + self.backend_server.clients[client.id] = client # type: ignore + self.backend_server.known_clients[client.id] = { # type: ignore + "last_seen": client.last_seen + } + + self.backend_server._save_known_clients() + client.status = ClientStatus.ONLINE + + self.logger.info(f"[+] Registered new client {client}")