Implemented browser-based web client alongside existing pygame desktop client with dual-protocol server architecture supporting both TCP and WebSocket. Backend Changes: - Refactored GameServer for dual-protocol support (TCP + WebSocket) - Added WebSocketHandler for handling WebSocket connections - Added HTTPServer using aiohttp for serving web client files - Updated protocol handling to work with both connection types - Server tracks clients with protocol metadata (TCP/WebSocket) - Protocol-agnostic message sending and broadcasting - Added WebSocket port (8889) and HTTP port (8000) configuration Web Client: - Complete HTML5/CSS/JavaScript implementation - Responsive dark-themed UI - HTML5 Canvas rendering matching pygame visual style - WebSocket connection with auto-detected server URL - Real-time multiplayer gameplay in browser - Player list with scores and status - Mobile-friendly responsive design Deployment Options: - Development: Built-in HTTP server for local testing - Production: Disable HTTP server, use nginx/Apache for static files - Flexible server configuration (--no-http, --no-websocket flags) - Comprehensive nginx/Apache deployment documentation New Files: - src/server/websocket_handler.py - WebSocket connection handler - src/server/http_server.py - Static file server - web/index.html - Web client interface - web/style.css - Responsive styling - web/protocol.js - Protocol implementation - web/game.js - Game client with Canvas rendering - web/README.md - Deployment documentation Updated Files: - requirements.txt - Added websockets and aiohttp dependencies - src/server/game_server.py - Dual-protocol support - src/shared/constants.py - WebSocket and HTTP port constants - run_server.py - Server options for web support - README.md - Web client documentation - CLAUDE.md - Architecture documentation Features: - Web and desktop clients can play together simultaneously - Same JSON protocol for both client types - Independent server components (disable what you don't need) - Production-ready with reverse proxy support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
242 lines
5.5 KiB
Markdown
242 lines
5.5 KiB
Markdown
# Web Client Deployment
|
|
|
|
This directory contains the web client for the Multiplayer Snake game.
|
|
|
|
## Development Mode
|
|
|
|
For local development, use the built-in HTTP server:
|
|
|
|
```bash
|
|
python run_server.py --name "Dev Server"
|
|
```
|
|
|
|
This starts:
|
|
- TCP server on port 8888 (for pygame clients)
|
|
- WebSocket server on port 8889 (for web clients)
|
|
- HTTP server on port 8000 (serving web files)
|
|
|
|
Access the web client at: http://localhost:8000
|
|
|
|
## Production Deployment with nginx
|
|
|
|
For production, disable the built-in HTTP server and use nginx to serve static files and proxy WebSocket connections.
|
|
|
|
### Step 1: Run server without HTTP
|
|
|
|
```bash
|
|
python run_server.py --no-http --host 0.0.0.0
|
|
```
|
|
|
|
### Step 2: Configure nginx
|
|
|
|
Create an nginx configuration file (e.g., `/etc/nginx/sites-available/snake-game`):
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name snake.example.com;
|
|
|
|
# Serve static web files
|
|
location / {
|
|
root /path/to/multiplayer-snake/web;
|
|
try_files $uri $uri/ /index.html;
|
|
|
|
# Cache static assets
|
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
}
|
|
|
|
# Proxy WebSocket connections
|
|
location /ws {
|
|
proxy_pass http://localhost:8889;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
# WebSocket timeouts
|
|
proxy_read_timeout 86400;
|
|
proxy_send_timeout 86400;
|
|
}
|
|
}
|
|
```
|
|
|
|
Enable the site:
|
|
|
|
```bash
|
|
sudo ln -s /etc/nginx/sites-available/snake-game /etc/nginx/sites-enabled/
|
|
sudo nginx -t
|
|
sudo systemctl reload nginx
|
|
```
|
|
|
|
### Step 3: Update web client URL
|
|
|
|
Users should connect to: `ws://snake.example.com/ws` (or `wss://` for SSL)
|
|
|
|
## SSL/TLS Support (HTTPS + WSS)
|
|
|
|
For secure connections with Let's Encrypt:
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name snake.example.com;
|
|
return 301 https://$server_name$request_uri;
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name snake.example.com;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/snake.example.com/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/snake.example.com/privkey.pem;
|
|
|
|
# SSL configuration
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_prefer_server_ciphers on;
|
|
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
|
|
|
|
# Static files
|
|
location / {
|
|
root /path/to/multiplayer-snake/web;
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
# Secure WebSocket
|
|
location /ws {
|
|
proxy_pass http://localhost:8889;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
proxy_read_timeout 86400;
|
|
proxy_send_timeout 86400;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Apache Configuration
|
|
|
|
For Apache with mod_proxy_wstunnel:
|
|
|
|
```apache
|
|
<VirtualHost *:80>
|
|
ServerName snake.example.com
|
|
DocumentRoot /path/to/multiplayer-snake/web
|
|
|
|
<Directory /path/to/multiplayer-snake/web>
|
|
Options -Indexes +FollowSymLinks
|
|
AllowOverride None
|
|
Require all granted
|
|
</Directory>
|
|
|
|
# WebSocket proxy
|
|
ProxyPass /ws ws://localhost:8889
|
|
ProxyPassReverse /ws ws://localhost:8889
|
|
|
|
# Enable WebSocket
|
|
RewriteEngine On
|
|
RewriteCond %{HTTP:Upgrade} websocket [NC]
|
|
RewriteCond %{HTTP:Connection} upgrade [NC]
|
|
RewriteRule /ws/(.*) ws://localhost:8889/$1 [P,L]
|
|
</VirtualHost>
|
|
```
|
|
|
|
Enable required modules:
|
|
|
|
```bash
|
|
sudo a2enmod proxy proxy_http proxy_wstunnel rewrite
|
|
sudo systemctl restart apache2
|
|
```
|
|
|
|
## Caddy Configuration
|
|
|
|
Caddy makes it even simpler with automatic HTTPS:
|
|
|
|
```
|
|
snake.example.com {
|
|
root * /path/to/multiplayer-snake/web
|
|
file_server
|
|
|
|
handle /ws {
|
|
reverse_proxy localhost:8889
|
|
}
|
|
}
|
|
```
|
|
|
|
## Systemd Service
|
|
|
|
Create `/etc/systemd/system/snake-game.service`:
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=Snake Game Server
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=www-data
|
|
WorkingDirectory=/path/to/multiplayer-snake
|
|
ExecStart=/path/to/multiplayer-snake/venv/bin/python run_server.py --no-http --host 0.0.0.0
|
|
Restart=always
|
|
RestartSec=10
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
Enable and start:
|
|
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable snake-game
|
|
sudo systemctl start snake-game
|
|
sudo systemctl status snake-game
|
|
```
|
|
|
|
## Firewall Configuration
|
|
|
|
Open required ports:
|
|
|
|
```bash
|
|
# HTTP/HTTPS (nginx/Apache)
|
|
sudo ufw allow 80/tcp
|
|
sudo ufw allow 443/tcp
|
|
|
|
# Game server TCP (if accessed directly)
|
|
sudo ufw allow 8888/tcp
|
|
|
|
# WebSocket (if not behind proxy)
|
|
sudo ufw allow 8889/tcp
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### WebSocket connection fails
|
|
|
|
- Check firewall rules
|
|
- Verify nginx/Apache WebSocket proxy configuration
|
|
- Check browser console for errors
|
|
- Test WebSocket endpoint: `wscat -c ws://your-server:8889`
|
|
|
|
### Static files not loading
|
|
|
|
- Verify nginx root path is correct
|
|
- Check file permissions: `chmod -R 755 /path/to/web`
|
|
- Check nginx error logs: `sudo tail -f /var/log/nginx/error.log`
|
|
|
|
### Game server not starting
|
|
|
|
- Check if ports are already in use: `sudo netstat -tulpn | grep 8889`
|
|
- Review server logs
|
|
- Verify Python dependencies are installed
|