websocket-relay/.agents/summary/architecture.md
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

135 lines
3.5 KiB
Markdown

# Architecture
## System Architecture Overview
```mermaid
graph TB
subgraph Clients
C1[WebSocket Client 1]
C2[WebSocket Client 2]
C3[WebSocket Client N]
end
subgraph "WebSocket Relay Server"
EP[HTTP/TLS Endpoint]
HUB[Hub - Connection Manager]
BC[Broadcast Channel]
MET[Prometheus Metrics]
end
subgraph Monitoring
PROM[Prometheus Scraper]
end
C1 -->|ws/wss| EP
C2 -->|ws/wss| EP
C3 -->|ws/wss| EP
EP --> HUB
HUB --> BC
BC -->|relay to all| C1
BC -->|relay to all| C2
BC -->|relay to all| C3
HUB --> MET
MET -->|:9090/metrics| PROM
```
## Design Pattern: Hub-and-Spoke
The application uses a **Hub-and-Spoke** (fan-out) pattern where:
1. **Hub** is the central coordinator managing all WebSocket connections
2. **Spokes** are individual WebSocket client connections
3. Every message received from any client is **broadcast to all connected clients**
```mermaid
graph LR
subgraph Hub
REG[Register Channel]
UNREG[Unregister Channel]
BCAST[Broadcast Channel]
CLIENTS[Client Map]
end
CONN[New Connection] --> REG
REG --> CLIENTS
DISC[Disconnection] --> UNREG
UNREG --> CLIENTS
MSG[Incoming Message] --> BCAST
BCAST --> CLIENTS
```
## Concurrency Model
The server uses Go's CSP (Communicating Sequential Processes) concurrency model:
```mermaid
sequenceDiagram
participant Client
participant Handler as HTTP Handler
participant Hub as Hub.Run() goroutine
participant Reader as ReadMessage goroutine
Client->>Handler: HTTP Upgrade Request
Handler->>Hub: register <- conn
Hub->>Hub: Add to clients map
Handler->>Reader: Start goroutine
loop Read Messages
Client->>Reader: WebSocket Frame
Reader->>Hub: broadcast <- message
Hub->>Hub: Iterate clients map
Hub->>Client: WriteMessage (fan-out)
end
Reader->>Hub: unregister <- conn (on error/close)
Hub->>Hub: Remove from clients map
```
### Goroutine Lifecycle
| Goroutine | Purpose | Lifetime |
|-----------|---------|----------|
| `main` | HTTP server, accepts connections | Application lifetime |
| `Hub.Run()` | Processes register/unregister/broadcast channels | Application lifetime |
| Per-client reader | Reads messages from a single client | Client connection lifetime |
| Metrics server | Serves `/metrics` endpoint | Application lifetime (if enabled) |
## Configuration Architecture
```mermaid
graph LR
CLI[CLI Flag: --config-file] --> LOAD[config.Load]
LOAD --> YAML[YAML Parser]
YAML --> CFG[Config Struct]
CFG --> SRV[Server Setup]
CFG --> TLS[TLS Config]
CFG --> MET[Metrics Setup]
```
## Security Model
- **TLS Support**: Optional TLS via cert/key PEM files
- **Origin Check**: `CheckOrigin` allows all origins (permissive for relay use case)
- **No Authentication**: The relay is designed as a transparent message forwarder
- **No Authorization**: All connected clients can send/receive all messages
## Deployment Architecture
```mermaid
graph TB
subgraph "Build Pipeline"
SRC[Source Code] --> CI[Gitea CI]
CI --> TEST[go test]
CI --> LINT[golangci-lint]
TAG[Git Tag v*] --> REL[Release Pipeline]
REL --> BIN_L[Linux amd64 Binary]
REL --> BIN_M[macOS arm64 Binary]
end
subgraph "Runtime"
BIN[Binary] --> CFG[config.yaml]
CFG --> SERVER[WebSocket Server :8443]
CFG --> METRICS[Metrics Server :9090]
end
```