# WebSocket Module - Real-Time Game Communication ## Purpose Real-time bidirectional communication using Socket.io. Primary interface between players and game engine - all game actions flow through WebSocket events. ## Architecture ``` Client (Browser) ↓ Socket.io ConnectionManager ↓ Event Handlers ↓ Game Engine → StateManager → Database ↓ Broadcast to All Players ``` ## Structure ``` app/websocket/ ├── connection_manager.py # Connection lifecycle & broadcasting └── handlers.py # Event handler registration (15 handlers) ``` ## ConnectionManager Manages connections, rooms, and broadcasting. **State**: - `user_sessions: Dict[str, str]` - sid → user_id - `game_rooms: Dict[str, Set[str]]` - game_id → sids **Key Methods**: ```python await manager.connect(sid, user_id) await manager.disconnect(sid) await manager.join_game(sid, game_id, role) await manager.broadcast_to_game(game_id, event, data) await manager.emit_to_user(sid, event, data) ``` ## Event Handlers (15 Total) ### Connection Events - `connect` - JWT authentication - `disconnect` - Cleanup sessions ### Game Flow - `join_game` - Join game room - `start_game` - Initialize game state - `get_game_state` - Request current state - `get_box_score` - Get statistics ### Decision Submission - `submit_defensive_decision` - Defense strategy - `submit_offensive_decision` - Offense strategy ### Manual Outcome Flow - `roll_dice` - Roll dice for play - `submit_manual_outcome` - Submit card result ### Substitutions - `submit_pinch_hitter` - Batting substitution - `submit_pitching_change` - Pitcher substitution - `submit_defensive_replacement` - Field substitution ### Lineup - `get_lineup` - Get team lineup ## Event Pattern ```python @sio.event async def event_name(sid, data): try: # 1. Validate input # 2. Get game state # 3. Process action # 4. Broadcast result except Exception as e: await emit_error(sid, str(e)) ``` ## Key Events Emitted | Event | Recipient | Purpose | |-------|-----------|---------| | `game_state_update` | Room | State changed | | `play_resolved` | Room | Play completed | | `decision_required` | User | Need input | | `error` | User | Error occurred | | `dice_rolled` | Room | Dice result | ## Common Tasks ### Broadcasting State Update ```python state_dict = state.model_dump() await manager.broadcast_to_game(game_id, "game_state_update", state_dict) ``` ### Error Handling ```python await manager.emit_to_user(sid, "error", {"message": str(e)}) ``` ## References - **Protocol Spec**: `../../.claude/implementation/websocket-protocol.md` - **Game Engine**: See `../core/CLAUDE.md` - **Frontend Integration**: See `frontend-sba/composables/CLAUDE.md` --- **Handlers**: 15/15 implemented | **Updated**: 2025-01-19