# Migration to aiohttp for WebSocket and HTTP ## Summary The control server has been refactored to use **aiohttp** for both WebSocket and HTTP endpoints, replacing the previous `websockets` library for the WebSocket server. ## What Changed ### 1. Server Architecture **Before:** - Separate `websockets` server on port 8765 - Separate `aiohttp` HTTP API server on port 8766 **After:** - Single `aiohttp` application serving both: - WebSocket endpoint: `ws://host:8765/ws` - HTTP API endpoints: `http://host:8765/api/*` - HTTP API also available on port 8766 for backward compatibility ### 2. Code Changes #### `/home/pi/lighting-controller/src/control_server.py` **Removed:** - `import websockets` - `handle_ui_client()` method (used websockets library) - `start_websocket_server()` method - `_websocket_server_task()` method **Added:** - `handle_websocket()` method using aiohttp's WebSocket support - Updated `start_http_server()` to include WebSocket endpoint - Combined server startup (HTTP and WebSocket on same port) **Key Differences:** ```python # OLD (websockets library) async def handle_ui_client(self, websocket): async for message in websocket: data = json.loads(message) await websocket.send(json.dumps(response)) # NEW (aiohttp) async def handle_websocket(self, request): ws = web.WebSocketResponse() await ws.prepare(request) async for msg in ws: if msg.type == web.WSMsgType.TEXT: data = json.loads(msg.data) await ws.send_json(response) return ws ``` #### `/home/pi/lighting-controller/Pipfile` Both `aiohttp` and `websockets` are now in the dependencies: - `aiohttp` - for server WebSocket and HTTP - `websockets` - for client connections to LED bars (in `networking.py`) ### 3. Client Changes Required **WebSocket URL Update:** Clients must update their connection URL to include the `/ws` path: ```javascript // OLD const ws = new WebSocket('ws://10.42.0.1:8765'); // NEW const ws = new WebSocket('ws://10.42.0.1:8765/ws'); ``` **Python Client:** ```python # OLD uri = "ws://10.42.0.1:8765" # NEW uri = "ws://10.42.0.1:8765/ws" ``` ### 4. HTTP API The HTTP API endpoints remain the same, but are now available on both ports: - **Primary:** `http://10.42.0.1:8765/api/color-palette` - **Backward Compatibility:** `http://10.42.0.1:8766/api/color-palette` ### 5. Configuration Environment variables remain the same: ```bash CONTROL_SERVER_HOST=0.0.0.0 CONTROL_SERVER_PORT=8765 HTTP_API_PORT=8766 ``` ## Benefits 1. **Unified Server:** Single aiohttp application handles all HTTP and WebSocket traffic 2. **Easier CORS:** Can add CORS middleware once for both REST and WebSocket 3. **Simpler Deployment:** One port for UI clients (WebSocket + API) 4. **Standard REST Patterns:** aiohttp's routing and middleware ecosystem 5. **Less Dependencies:** One web framework instead of two ## Testing ### Test WebSocket Connection ```bash # Python test client pipenv run python test/test_control_server.py --pattern rainbow ``` ### Test HTTP API ```bash # Get color palette curl http://localhost:8765/api/color-palette # Update selected colors curl -X POST http://localhost:8765/api/color-palette \ -H "Content-Type: application/json" \ -d '{"selected_indices": [3, 6]}' ``` ## Backward Compatibility - HTTP API still available on port 8766 - WebSocket protocol unchanged (JSON message format) - Only the WebSocket URL path changed (added `/ws`) ## Files Modified 1. `/home/pi/lighting-controller/src/control_server.py` - Main refactor 2. `/home/pi/lighting-controller/Pipfile` - Dependencies (kept both aiohttp and websockets) 3. `/home/pi/lighting-controller/COLOR_PALETTE_API.md` - Updated documentation ## Files NOT Modified - `/home/pi/lighting-controller/src/networking.py` - Still uses `websockets` for client connections - `/home/pi/lighting-controller/src/ui_client.py` - UI being worked on elsewhere (needs URL update) - `/home/pi/led-bar/*` - No changes needed