from ..utils.observable import Observable, Event as ObservableEvent from ..utils.wrapper_util import threaded from .connection import Connection, EVENTS as CONNECTION_EVENTS from enum import Enum import logging, traceback import socket import random class EVENTS(Enum): ON_START = 0 ON_START_ERROR = 1 ON_CONNECTION = 2 ON_CONNECTION_ERROR = 3 ON_DISCONNECTION = 4 ON_MESSAGE = 5 class Server(Observable): def __init__(self): super().__init__() self.connections:dict[tuple[str,int],Connection] = {} self.bind_address = None self.running = False self.user = None @threaded def run(self, user, pmc, bind_address = ('127.0.0.1', random.randint(5000, 5999))): try: self.user = user if not bind_address: self.bind_address = ('127.0.0.1', random.randint(5000, 5999)) else: self.bind_address = bind_address logging.info(f"Starting server on address {self.bind_address}") s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(self.bind_address) s.settimeout(10) s.listen(5) self.running = True self.fire_event(EVENTS.ON_START) logging.info(f"Listening on {self.bind_address}") while True: try: conn, addr = s.accept() logging.info(f"Incoming connection: {addr}") connection = Connection(user, pmc, conn) connection.subscribe_event(CONNECTION_EVENTS.ON_CONNECTION, self.on_server_connection) connection.subscribe_event(CONNECTION_EVENTS.ON_MESSAGE, self.on_server_message) connection.subscribe_event(CONNECTION_EVENTS.ON_DISCONNECTION, self.on_server_disconnection) self.connections[addr] = connection self.connections[addr].new_connection() except socket.timeout: continue except Exception: logging.error("ERROR") conn.close() except Exception as e: logging.error("ERROR") self.fire_event(EVENTS.ON_START_ERROR, error=e) def on_server_connection(self, event:ObservableEvent): pass def on_server_message(self, event): pass def on_server_disconnection(self, event): pass