commit a878ba6cc59133e0365dc04deef85432655e5f5b Author: Hirviturkki Date: Mon Apr 21 16:33:53 2025 +0200 Added all files diff --git a/DockerFile b/DockerFile new file mode 100644 index 0000000..b8fb995 --- /dev/null +++ b/DockerFile @@ -0,0 +1,7 @@ +FROM python:3.11-slim +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY server.py . +EXPOSE 8080 +CMD ["python", "server.py"] diff --git a/deployment.yaml b/deployment.yaml new file mode 100644 index 0000000..20584f4 --- /dev/null +++ b/deployment.yaml @@ -0,0 +1,28 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: webrtc-signal +spec: + replicas: 1 + selector: + matchLabels: { app: webrtc-signal } + template: + metadata: + labels: { app: webrtc-signal } + spec: + containers: + - name: server + image: yourrepo/webrtc-signal:1.0 + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: webrtc-signal +spec: + type: NodePort # or LoadBalancer if you have MetalLB + selector: { app: webrtc-signal } + ports: + - port: 8080 # cluster‑internal + targetPort: 8080 # container diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6259e61 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +websockets==12.0 \ No newline at end of file diff --git a/server.py b/server.py new file mode 100644 index 0000000..6525bb3 --- /dev/null +++ b/server.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +""" +Minimal signalling relay for WebRTC data‑channel projects. + +Contract: +• Client sends {"type":"register","id": "..."} once on connect. +• Later it sends {"type":"signal","from": "...", "target": "...", "data": {...}} + The server forwards that JSON verbatim to the socket whose id == target. +""" + +import asyncio, json, logging +import websockets + +logging.basicConfig(level=logging.INFO) +CLIENTS: dict[str, websockets.WebSocketServerProtocol] = {} + +async def handler(ws: websockets.WebSocketServerProtocol): + peer_id = None + try: + async for raw in ws: + try: + msg = json.loads(raw) + except json.JSONDecodeError: + logging.warning("Bad JSON from %s: %s", peer_id, raw) + continue + + mtype = msg.get("type") + if mtype == "register": + peer_id = msg.get("id") + if not peer_id: + await ws.close(code=4000, reason="Missing id") + return + CLIENTS[peer_id] = ws + logging.info("Registered %s (%d clients)", peer_id, len(CLIENTS)) + + elif mtype == "signal": + target = msg.get("target") + if not target: + continue + dest = CLIENTS.get(target) + if dest: + await dest.send(raw) # relay as‑is + logging.debug("Relayed %s → %s", peer_id, target) + else: + logging.warning("Target %s not found", target) + + except websockets.ConnectionClosed: + pass + finally: + # tidy up on disconnect + if peer_id and CLIENTS.get(peer_id) is ws: + CLIENTS.pop(peer_id) + logging.info("Disconnected %s (%d clients left)", peer_id, len(CLIENTS)) + +async def main(): + async with websockets.serve(handler, host="0.0.0.0", port=8080): + logging.info("Signalling server listening on :8080") + await asyncio.Future() # run forever + +if __name__ == "__main__": + asyncio.run(main())