savinmax 8eaba398dc feat(hub): update register/unregister to use Inc/Dec metrics and add room-aware tests
- Change ConnectedClients metrics from Set() to Inc()/Dec() pattern
  for cleaner, atomic metric updates in register/unregister/broadcast
- Add room info to unregister and broadcast-cleanup log messages
- Handle unregistered connections gracefully (close without panic)
- Capture count inside lock for accurate log output

Tests added:
- TestRegisterClient: verifies ClientCount/RoomCount after connect
- TestUnregisterClient: verifies cleanup after disconnect
- TestRegisterMultipleRooms: verifies multi-room state tracking
- TestUnregisterCleansUpEmptyRoom: verifies empty room deletion
- TestUnregisterUnknownConnNoPanic: verifies no panic on unknown conn

All tests pass including race detector.

🤖 Assisted by the code-assist SOP
2026-06-13 13:14:57 +02:00
2025-08-02 21:00:28 +02:00
2025-08-02 18:33:50 +02:00
2025-08-02 18:33:50 +02:00
2025-08-02 18:33:50 +02:00
2025-08-02 18:33:50 +02:00

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

# 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:

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:

./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:

# 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:

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:

const ws = new WebSocket('wss://localhost:8443/');

All messages sent by any client are broadcast to every connected client (including the sender).

Build

make build      # Build binary → build/websocket-relay
make release    # Cross-compile linux/amd64 + darwin/arm64
make clean      # Remove build artifacts

Testing

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.

Description
A minimal Go WebSocket relay server with SSL support for P2P connections.
Readme 122 KiB
2025-08-02 21:31:35 +02:00
Languages
Go 86.2%
HTML 13.1%
Makefile 0.7%