cw-generator/signalsrv/signalsrv2.py

82 lines
2.1 KiB
Python

import json
import socketserver
__VERSION__ = "0.0.1"
# https://websockets.readthedocs.io/en/stable/reference/asyncio/server.html
class LobbyMgr:
__instance = None
def __new__(cls):
if cls.__instance is None:
cls.__instance = LobbyMgr()
return cls.__instance
class LobbyHandler(socketserver.StreamRequestHandler):
def handle(self):
print(f" >>> New client {self.client} connected")
exc = None
try:
self._handle_client()
except Exception as e:
exc = e
finally:
print(f" <<< Client {self.client} disconnected: {exc}")
@property
def client(self):
return f"{':'.join(map(str, self.client_address))}"
def _handle_client(self):
self._send(type="hello", name="LobbySrv 3000", version=__VERSION__)
while True:
data = self.rfile.readline(10000).rstrip()
print(f" <-- client {self.client} sent {repr(data)}")
if not data.strip():
continue
try:
data = json.loads(data)
except json.JSONDecodeError:
self._send_error("Could not decode message, invalid json")
continue
if not isinstance(data, dict) or "cmd" not in data:
self._send_error("Invalid format in json")
continue
print(f"{self.client_address[0]} wrote:", data)
match data["cmd"]:
case "quit":
break
case _:
self._send_error("Unknown command")
def _send(self, **kwargs):
data = json.dumps(kwargs).encode()
print(f" --> sending out to {self.client}: {data}")
self.wfile.write(json.dumps(kwargs).encode() + b"\n")
def _send_error(self, msg: str):
self._send(type="error", message=msg)
class LobbyServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
allow_reuse_address = True
def main():
HOST, PORT = "localhost", 3784
with LobbyServer((HOST, PORT), LobbyHandler) as server:
server.serve_forever()
if __name__ == "__main__":
main()