import asyncio import websockets import json import logging from asyncio import CancelledError from websockets import InvalidUpgrade, ConnectionClosed, ConnectionClosedError from aiohttp import web from app.class_settings import Settings from app.class_file_path import Path from app.class_file_convert import Convert from app.class_media_file_stat import Stat var_convert_active = False class Server: def __init__(self): self.websocket = None self.clients = set() obj_settings = Settings() obj_settings.set_logging() self.yaml = obj_settings.yaml self.obj_path = Path(self.yaml) self.obj_convert = Convert(self, self.yaml, self.obj_path) async def send_websocket(self, message): message_json = json.dumps(message) for client in self.clients.copy(): try: await client.send(message_json) except websockets.exceptions.ConnectionClosed: self.clients.remove(client) async def handle_client(self, websocket): self.websocket = websocket self.clients.add(websocket) global var_convert_active try: async for message in websocket: data = json.loads(message) if data.get("data_path"): self.obj_path.receive_paths(data.get("data_path")) if var_convert_active == False and self.yaml['autostart']: await self.obj_convert.snake_waiting() var_convert_active = True else: self.obj_convert.snake_update() elif data.get("data_command"): pass elif data.get("data_message"): logging.info(f"Server hat Empfangen: {data.get('data_message')}") except (ConnectionClosedError, ConnectionClosed): logging.warning("Client Verbindung geschlossen") except InvalidUpgrade: logging.warning("Ungültiger Websocket Upgrade versuch") except Exception as e: logging.error(f"Unerwarteter Fehler {e}") finally: self.clients.discard(websocket) @staticmethod def set_var_convert_active(value: bool): global var_convert_active var_convert_active = value async def server_websocket(self): server = await websockets.serve(self.handle_client, self.yaml['server_ip'], self.yaml['server_port']) logging.info(f"Websocket Server läuft auf IP: {self.yaml['server_ip']} Port: {self.yaml['server_port']}") await server.wait_closed() # WebServer -------------------------------------------------------------------------------------------------------- @staticmethod async def handle_index(request): return web.FileResponse("./client/index.html") async def handle_ip(self, request): ip = self.yaml.get("server_ip", "localhost") port = self.yaml.get("server_port", 8000) return web.json_response({"server_ip": ip, "server_port": port}) @staticmethod async def handle_stat(request): obj_stat = Stat() return web.json_response(obj_stat.read_stat()) async def server_http(self): app = web.Application() app.router.add_get("/", self.handle_index) app.router.add_get("/api/ip", self.handle_ip) app.router.add_get("/api/stats", self.handle_stat) app.router.add_static("/client/", path="./client", name="client") runner = web.AppRunner(app) await runner.setup() site = web.TCPSite(runner, "0.0.0.0", 8080) await site.start() logging.info("HTTP Server läuft auf Port 8080") # Start Server ----------------------------------------------------------------------------------------------------- async def start_server(self): try: await asyncio.gather( self.server_websocket(), self.server_http() ) except CancelledError: logging.warning("Server wurde durch Keyboard Interrupt gestoppt.") except Exception as e: logging.error(f"Unerwarteter Fehler beim Starten des Servers {e}")