Websockets instead of polling

This commit is contained in:
2026-06-12 06:19:22 -07:00
parent b72aea9747
commit ba6bf35579
8 changed files with 128 additions and 8 deletions

View File

@@ -1,15 +1,17 @@
from contextlib import asynccontextmanager
from typing import Optional
from fastapi import FastAPI, Form, Depends, HTTPException, APIRouter
from fastapi import FastAPI, Form, Depends, HTTPException, APIRouter, WebSocket, WebSocketDisconnect
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from sqlmodel import Session
import re
import uvicorn
import os
from pathlib import Path
from . import crud
from .database import create_db_and_tables, get_session
from .ws import manager
EVENT_PAGE_SIZE = 50
@@ -23,6 +25,31 @@ async def lifespan(app: FastAPI):
app = FastAPI(title="Rats with Gats Remote Play API", lifespan=lifespan)
api = APIRouter()
# Every state mutation is a POST under /api/game/{game_id}/..., so one
# middleware can notify a game's websocket clients after any successful write.
GAME_PATH_RE = re.compile(r"^/api/game/([^/]+)/")
@app.middleware("http")
async def broadcast_state_changes(request, call_next):
response = await call_next(request)
if request.method == "POST" and response.status_code < 400:
match = GAME_PATH_RE.match(request.url.path)
if match:
await manager.broadcast(match.group(1), {"type": "state_changed"})
return response
@app.websocket("/api/game/{game_id}/ws")
async def game_websocket(websocket: WebSocket, game_id: str):
await manager.connect(game_id, websocket)
try:
while True:
# Clients don't send anything meaningful; this just detects disconnects.
await websocket.receive_text()
except WebSocketDisconnect:
pass
finally:
manager.disconnect(game_id, websocket)
# --- API Core Route Handlers ---
@api.post("/game")