Websockets instead of polling
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user