brackt/plans/phase-3-socket-implementation-summary.md

112 lines
3.3 KiB
Markdown
Raw Normal View History

# Phase 3: Socket.IO Implementation - Summary
## Key Decision: Modify server.js (Option A)
After researching React Router v7 + Socket.IO integration patterns, the recommended approach is:
### Why This Approach?
1. **Industry Standard**: Socket.IO requires `http.createServer(app)` - this is the documented pattern
2. **Single Port**: HTTP and WebSocket traffic on same port (simpler deployment)
3. **No CORS Issues**: Everything runs on same origin
4. **Works with SSR**: Compatible with React Router v7's server-side rendering
5. **Simpler Deployment**: One process, one port, one service
### What Changes?
**Minimal changes to `server.js`:**
```javascript
// Before:
app.listen(PORT, () => {...});
// After:
import { createServer } from "http";
const httpServer = createServer(app);
const { initializeSocketIO } = await import("./server/socket.js");
initializeSocketIO(httpServer);
httpServer.listen(PORT, () => {...});
```
That's it! Just 4 lines changed in server.js.
## Alternative Considered: Separate Socket Server (Option B)
**Why we rejected this:**
- Requires managing two processes
- CORS configuration complexity
- Different ports (3000 for HTTP, 3001 for WebSocket)
- More complex deployment (two services)
- Not the standard pattern
**When to use Option B:**
- If you absolutely cannot modify server.js
- If you need to scale WebSocket separately from HTTP
- If you're using a microservices architecture
## Implementation Steps
### Step 1: Create Socket Module
- File: `server/socket.js` (not .ts to avoid bundling)
- Exports: `initializeSocketIO()` and `getSocketIO()`
- Stores instance globally for route handlers
### Step 2: Modify server.js
- Import `http.createServer`
- Create HTTP server from Express app
- Initialize Socket.IO with HTTP server
- Call `httpServer.listen()` instead of `app.listen()`
### Step 3: Client Hook
- Create `app/hooks/useDraftSocket.ts`
- Handles connection/disconnection
- Auto-joins draft room on connect
- Provides `on`/`off` helpers for events
### Step 4: Route Handlers
- Import `getSocketIO()` in API routes
- Emit events after database writes
- Example: After creating pick, emit `pick-made` to room
## Event Architecture
**Write Operations → HTTP POST**
- Making picks
- Queue management
- Commissioner actions
- Reason: Reliability, error handling, validation
**Read Operations → Socket.IO Broadcast**
- Pick made notifications
- Timer updates
- Draft status changes
- Reason: Real-time updates to all clients
## Testing Checklist
- [ ] Server starts with "Socket.IO initialized"
- [ ] Browser console shows "Connected to Socket.IO"
- [ ] Server logs show "Client connected: [id]"
- [ ] Multiple clients can join same draft room
- [ ] Picks broadcast to all clients in room
- [ ] Disconnection handled gracefully
## Production Notes
- Socket.IO auto-upgrades from polling → WebSocket
- Load balancer needs sticky sessions for WebSocket
- Monitor connection counts
- Consider Redis adapter for horizontal scaling (future)
## Files Created/Modified
**New Files:**
- `server/socket.js` - Socket.IO initialization
- `server/types.d.ts` - TypeScript globals
- `app/hooks/useDraftSocket.ts` - Client hook
**Modified Files:**
- `server.js` - 4 lines changed (http.createServer)
- `tsconfig.node.json` - Add server directory
**Total LOC:** ~150 lines of new code