# WebSocket Relay Server A minimal Go WebSocket relay server that broadcasts every incoming message to all connected clients. Supports TLS, Prometheus metrics, and graceful shutdown. ## Features - **Fan-out broadcasting** — every message is relayed to all connected clients - **TLS support** — optional `wss://` via cert/key PEM files - **Prometheus metrics** — connection counts, message totals, disconnections - **Graceful shutdown** — clean exit on SIGINT/SIGTERM with client notification - **Zero dependencies at runtime** — single static binary ## Quick Start ```bash # Install dependencies go mod tidy # Run the server (defaults to ws://localhost:8443) make run # Or with a custom config go run . --config-file=./config.yaml ``` Open `example/index.html` in multiple browser tabs to test the P2P chat demo. ## Configuration Edit `config.yaml`: ```yaml server: port: 8443 tls: enabled: false # Set true for wss:// cert_file: cert.pem key_file: key.pem metrics: enabled: true port: 9090 # Prometheus metrics at :9090/metrics ``` Override the config file path with `--config-file`: ```bash ./websocket-relay --config-file=/etc/relay/config.yaml ``` ## Usage Connect any WebSocket client to the server: ```javascript const ws = new WebSocket('ws://localhost:8443/'); ws.onmessage = (event) => console.log('Received:', event.data); ws.onopen = () => ws.send('Hello from client!'); ``` With TLS enabled: ```javascript const ws = new WebSocket('wss://localhost:8443/'); ``` All messages sent by any client are broadcast to every connected client (including the sender). ## Build ```bash make build # Build binary → build/websocket-relay make release # Cross-compile linux/amd64 + darwin/arm64 make clean # Remove build artifacts ``` ## Testing ```bash make test # Run all tests (unit + integration) ``` ## Metrics When `metrics.enabled` is `true`, Prometheus metrics are exposed at `http://localhost:9090/metrics`: | Metric | Type | Description | |--------|------|-------------| | `websocket_connected_clients` | Gauge | Currently connected clients | | `websocket_messages_total` | Counter | Total messages relayed | | `websocket_connections_total` | Counter | Total connections established | | `websocket_disconnections_total` | Counter | Total disconnections | ## Graceful Shutdown The server handles `SIGINT` and `SIGTERM` signals: 1. Stops accepting new connections 2. Sends WebSocket `CloseGoingAway` frame to all connected clients 3. Closes all connections and exits cleanly Shutdown timeout is 10 seconds. ## Project Structure ``` websocket-relay/ ├── main.go # Entry point, signal handling, graceful shutdown ├── internal/ │ ├── config/config.go # YAML config loader │ ├── hub/hub.go # WebSocket hub, connection management, broadcast │ └── metrics/metrics.go # Prometheus metric definitions ├── example/index.html # Browser P2P chat demo ├── config.yaml # Runtime configuration ├── config.example.yaml # Example config with TLS enabled └── Makefile # Build, test, release commands ``` ## License See repository for license details.