- 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
3.2 KiB
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
CheckOriginaccepts 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