diff --git a/src/judas_client/__main__.py b/src/judas_client/__main__.py index 71126fb..dac7f6f 100644 --- a/src/judas_client/__main__.py +++ b/src/judas_client/__main__.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging as lg -from judas_client.connector import Connector +from judas_client.client import Client if __name__ == "__main__": lg.basicConfig( @@ -12,5 +12,5 @@ if __name__ == "__main__": ) logger = lg.getLogger(__name__) - connector = Connector("127.0.0.1", 3692) - connector.run() + client = Client(server_host="localhost", server_port=3692) + client.run() diff --git a/src/judas_client/client.py b/src/judas_client/client.py new file mode 100644 index 0000000..cde27d0 --- /dev/null +++ b/src/judas_client/client.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +"""Client module for handling messages.""" + +from __future__ import annotations + +import logging as lg +import uuid + +from judas_protocol import Message + +from judas_client.connector import Connector + + +class Client: + """Client class for handling messages.""" + + def __init__(self, server_host: str, server_port: int) -> None: + """Initialize the Client. + + Args: + server_host (str): The server host address. + server_port (int): The server port number. + """ + self.logger: lg.Logger = lg.getLogger( + f"{__name__}.{self.__class__.__name__}" + ) + self.logger.debug("Initializing Client...") + + self.server_host: str = server_host + self.server_port: int = server_port + + self.mac_address: str = self._get_mac_address() + self.logger.debug(f"MAC address: {self.mac_address}") + + self.connector: Connector = Connector( + mac_address=self.mac_address, + host=self.server_host, + port=self.server_port, + on_message=self.handle_message, + ) + + def _get_mac_address(self) -> str: + """Get the MAC address of the client. + + Returns: + str: The MAC address in standard lowercase format (e.g., "0a:1b:2c:3d:4e:5f"). + """ + mac_address: str = ":".join( + [ + "{:02x}".format((uuid.getnode() >> ele) & 0xFF) + for ele in range(0, 8 * 6, 8) + ][::-1] + ) + return mac_address + + def handle_message(self, message: Message) -> None: + """Handle incoming messages. + + Args: + message (Message): The incoming message to handle. + """ + self.logger.info(f"[v] Received message: {message}") + + def run(self) -> None: + """Run the client.""" + self.logger.info(f"Starting Client ({self.mac_address})...") + self.connector.run() diff --git a/src/judas_client/connector.py b/src/judas_client/connector.py index 0187c06..2488e37 100644 --- a/src/judas_client/connector.py +++ b/src/judas_client/connector.py @@ -4,7 +4,7 @@ from __future__ import annotations import logging as lg import socket import time -import uuid +from typing import Callable from judas_protocol import Message @@ -12,10 +12,13 @@ from judas_protocol import Message class Connector: def __init__( self, + mac_address: str, host: str, port: int, + *, connect_timeout: float = 5.0, ack_timeout: float | None = None, + on_message: Callable[[Message], None], ) -> None: self.logger: lg.Logger = lg.getLogger( f"{__name__}.{self.__class__.__name__}" @@ -32,17 +35,9 @@ class Connector: socket.AF_INET, socket.SOCK_STREAM ) - self.mac_address: str = self._get_mac_address() + self.mac_address: str = mac_address - def _get_mac_address(self) -> str: - mac_address: str = ":".join( - [ - "{:02x}".format((uuid.getnode() >> ele) & 0xFF) - for ele in range(0, 8 * 6, 8) - ][::-1] - ) - self.logger.debug(f"MAC address: {mac_address}") - return mac_address + self.on_message: Callable[[Message], None] = on_message def _send_ack(self) -> None: self.logger.debug("[>] Sending ACK...") @@ -165,15 +160,28 @@ class Connector: time.sleep(1) def _loop(self) -> None: - self.logger.debug("Starting main loop...") + self.logger.debug("Starting connector loop...") while True: - time.sleep(1) + time.sleep(0.1) data: bytes = self.receive() if not data: self.reconnect() continue - message = Message.from_bytes(data.strip()) - self.logger.info(f"[<] Message received: {message}") + for line in data.split(b"\n"): + line: bytes = line.strip() + + if not line: + continue + + self.logger.debug(f"[.] Raw message data: {line}") + try: + message: Message = Message.from_bytes(line) + except ValueError as e: + self.logger.error(f"[!] Failed to parse message: {e}") + continue + self.logger.info(f"[*] Message received: {message}") + self.on_message(message) + # if self._check_ack(): # self.logger.debug("[.] ACK verified") # else: diff --git a/uv.lock b/uv.lock index 737c51a..ca96414 100644 --- a/uv.lock +++ b/uv.lock @@ -292,8 +292,8 @@ test = [ [[package]] name = "judas-protocol" -version = "0.1.0" -source = { git = "https://gitea.pufereq.pl/judas/judas_protocol.git#fd070b176347a0f7b81f937b189d8f50736f3514" } +version = "0.2.0" +source = { git = "https://gitea.pufereq.pl/judas/judas_protocol.git#bc1bf46388eb904738893a2f86b5050b4ce2489e" } [[package]] name = "markdown-it-py"