savinmax 905c241daa
Some checks failed
CI / test (push) Successful in 54s
CI / lint (push) Failing after 3m16s
Improve reliability, testing, and documentation
- 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
2026-06-11 19:14:19 +02:00

3.2 KiB

Interfaces

HTTP Endpoints

WebSocket Endpoint

Property Value
Path /
Protocol WebSocket (ws:// or wss://)
Port Configurable (default: 8443)
Handler hub.HandleWebSocket

Upgrade Headers:

  • Standard WebSocket upgrade
  • CheckOrigin accepts all origins

Message Protocol:

  • Type: TextMessage (opcode 1)
  • Format: Raw bytes (no structured format imposed)
  • Direction: Bidirectional — any message sent is broadcast to all connected clients
sequenceDiagram
    participant A as Client A
    participant S as Relay Server
    participant B as Client B
    participant C as Client C

    A->>S: Connect (ws upgrade)
    B->>S: Connect (ws upgrade)
    C->>S: Connect (ws upgrade)
    A->>S: Send "Hello"
    S->>A: Relay "Hello"
    S->>B: Relay "Hello"
    S->>C: Relay "Hello"

Note: The sender also receives their own message back (no sender filtering).


Metrics Endpoint

Property Value
Path /metrics
Protocol HTTP
Port Configurable (default: 9090)
Format Prometheus text exposition format
Condition Only available when metrics.enabled: true

Available Metrics:

# HELP websocket_connected_clients Number of currently connected WebSocket clients
# TYPE websocket_connected_clients gauge
websocket_connected_clients 0

# HELP websocket_message Number of WebSocket messages processed
# TYPE websocket_message gauge
websocket_message 0

# HELP websocket_connection Number of WebSocket connections established
# TYPE websocket_connection gauge
websocket_connection 0

# HELP websocket_disconnection Number of WebSocket disconnections
# TYPE websocket_disconnection gauge
websocket_disconnection 0

CLI Interface

Usage: websocket-relay [flags]

Flags:
  --config-file string   Path to configuration file (default "config.yaml")

Configuration Interface (YAML)

server:
  port: 8443              # Server listen port
  tls:
    enabled: true         # Enable TLS (wss://)
    cert_file: cert.pem   # Path to TLS certificate
    key_file: key.pem     # Path to TLS private key

metrics:
  enabled: true           # Enable Prometheus metrics endpoint
  port: 9090             # Metrics server port

Internal Go Interfaces (Implicit)

The codebase doesn't define explicit Go interfaces but uses the following implicit contracts:

Hub Contract

// Hub manages WebSocket connections and broadcasts messages
type Hub interface {
    Run()                                           // Start event loop
    HandleWebSocket(http.ResponseWriter, *http.Request)  // HTTP handler
    ClientCount() int                               // Connected client count
}

Config Contract

// Config loading
type ConfigLoader interface {
    Load(filename string) (*Config, error)
}

Integration Points

graph LR
    subgraph External
        PROM[Prometheus]
        BROWSERS[Browser Clients]
        APPS[Application Clients]
    end

    subgraph "WebSocket Relay"
        WS[WebSocket :8443]
        MET[Metrics :9090]
    end

    BROWSERS -->|ws/wss| WS
    APPS -->|ws/wss| WS
    PROM -->|HTTP GET /metrics| MET