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