import socket from threading import Thread class SocketServer(Thread): __BLOCK_SIZE = 1024 def __init__(self, host: "str", port: "int"): super().__init__() self.__socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.__socket.bind((host, port)) self.__socket.listen(1) self.__server_msg = f"server running on ws://{host}:{port}" self.__clients, self.__handlers = [], {} def __receive(self, client: "socket.socket"): try: buffer = b"" while True: buffer += client.recv(SocketServer.__BLOCK_SIZE) while (index := buffer.find(b"==END==")) > -1: pool, buffer = buffer[:index], buffer[index + 7:] index = pool.find(b"==EVENT:") if index != -1: pool = pool[index + 8:] index = pool.find(b"==") self.__event_handler(client, pool[:index].decode("utf-8"), pool[index + 2:]) finally: client.close() def __event_handler(self, client: "socket.socket", event: "str", data): if event in self.__handlers.keys(): Thread(target=self.__handlers[event], args=(client, data), name=f"{event}-handler").start() def on(self, event: "str"): def decorator(func): self.__handlers[event] = func return func return decorator @staticmethod def emit(client: "socket.socket", event: "str", msg: "bytes" = b""): client.sendall(f"==EVENT:{event}==".encode("utf-8") + msg + b"==END==") def broadcast(self, msg: "bytes"): for client in self.__clients: self.emit(client, "bios", msg) def run(self) -> None: print(self.__server_msg) while True: client, addr = self.__socket.accept() self.__event_handler(client, "connect", addr) Thread(target=self.__receive, args=(client,), name=f"{addr}-receiver").start()