from aiohttp import web import json # Storage for active handshake sessions sessions = {} # Cloudflare TURN Credentials ICE_CONFIG = { "iceServers": [ {"urls": "stun:stun.cloudflare.com:3478"}, { "urls": "turn:turn.cloudflare.com:5349", "username": "g08abe68c81a07f098bb5f0914549bb32440e5aad0b216c7fba2b61e76fd62c6", "credential": "aed1a10dd10eba9401ad9d99e5c66036d8a970eab5ba8e6dc9845ab57c771a7d" } ] } async def handle_post(request): data = await request.json() sid = data.get("id") msg_type = data.get("type") if not sid: return web.json_response({"error": "No ID"}, status=400) if sid not in sessions: sessions[sid] = {"offer": None, "answer": None, "candidates": []} if msg_type == "offer": sessions[sid]["offer"] = data["payload"] elif msg_type == "answer": sessions[sid]["answer"] = data["payload"] elif msg_type == "candidate": sessions[sid]["candidates"].append(data["payload"]) return web.json_response({"status": "stored"}) async def handle_get(request): sid = request.query.get("id") if not sid or sid not in sessions: return web.json_response({"status": "waiting", "offer": None, "iceConfig": ICE_CONFIG}) resp = sessions[sid].copy() resp["iceConfig"] = ICE_CONFIG return web.json_response(resp) async def cors_middleware(app, handler): async def middleware(request): if request.method == 'OPTIONS': resp = web.Response() else: resp = await handler(request) resp.headers['Access-Control-Allow-Origin'] = '*' resp.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS' resp.headers['Access-Control-Allow-Headers'] = 'Content-Type' return resp return middleware app = web.Application(middlewares=[cors_middleware]) app.router.add_post('/signal', handle_post) app.router.add_get('/signal', handle_get) if __name__ == '__main__': print("Broker running at http://localhost:3000") web.run_app(app, port=3000)