- Fix metrics: change MessagesTotal, ConnectionsTotal, DisconnectionsTotal from Gauge to Counter with proper _total naming convention - Fix broadcast write-error handling: failed clients now get properly removed with accurate metrics updates - Add graceful shutdown: SIGINT/SIGTERM handling with 10s timeout, CloseGoingAway frame sent to clients before disconnect - Add integration tests: 11 tests using real WebSocket connections covering connect, broadcast, disconnect, concurrency, and shutdown - Fix example client port: changed from 8000 to 8443 to match config - Rewrite README.md to reflect current features and usage - Add AGENTS.md and .agents/summary/ documentation for AI assistants
123 lines
3.2 KiB
Markdown
123 lines
3.2 KiB
Markdown
# 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.
|