# WebSocket Relay Server A minimal Go WebSocket relay server that broadcasts every incoming message to all connected clients. Supports TLS, Prometheus metrics, configurable logging, 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 - **Configurable logging** — output to stdout, stderr, or file with level filtering - **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 logging: output: stderr # stdout, stderr, or a file path level: info # debug, info, warn, error ``` Override the config file path with `--config-file`: ```bash ./websocket-relay --config-file=/etc/relay/config.yaml ``` ## Logging The `logging` section controls where and what the server logs: | Field | Values | Default | Description | |-------|--------|---------|-------------| | `output` | `stdout`, `stderr`, or a file path | `stderr` | Log output destination | | `level` | `debug`, `info`, `warn`, `error` | `info` | Minimum log level to output | **Examples:** ```yaml # Log everything to a file logging: output: /var/log/websocket-relay.log level: debug # Quiet mode — only warnings and errors to stderr logging: output: stderr level: warn ``` Log messages are prefixed with the level: `[DEBUG]`, `[INFO]`, `[WARN]`, `[ERROR]`. File output uses append mode (`O_APPEND`) so logs are preserved across restarts and safe for external log rotation tools. ## 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 │ ├── logging/logging.go # Log output setup and leveled logger │ └── metrics/metrics.go # Prometheus metric definitions ├── example/index.html # Browser P2P chat demo ├── config.yaml # Runtime configuration ├── config.example.yaml # Example config with TLS and logging └── Makefile # Build, test, release commands ``` ## License See repository for license details.