handleWebSocket handles WebSocket connections for real-time updates
(w http.ResponseWriter, r *http.Request)
| 141 | |
| 142 | // handleWebSocket handles WebSocket connections for real-time updates |
| 143 | func (ds *DashboardServer) handleWebSocket(w http.ResponseWriter, r *http.Request) { |
| 144 | conn, err := ds.upgrader.Upgrade(w, r, nil) |
| 145 | if err != nil { |
| 146 | shared.LogErrorf("Failed to upgrade WebSocket connection: %v", err) |
| 147 | return |
| 148 | } |
| 149 | |
| 150 | ds.clientsMu.Lock() |
| 151 | ds.clients[conn] = true |
| 152 | ds.clientsMu.Unlock() |
| 153 | |
| 154 | shared.LogInfof("New WebSocket client connected, total clients: %d", len(ds.clients)) |
| 155 | |
| 156 | // Handle client disconnection |
| 157 | defer func() { |
| 158 | ds.clientsMu.Lock() |
| 159 | delete(ds.clients, conn) |
| 160 | ds.clientsMu.Unlock() |
| 161 | conn.Close() |
| 162 | shared.LogInfof("WebSocket client disconnected, remaining clients: %d", len(ds.clients)) |
| 163 | }() |
| 164 | |
| 165 | // Send initial dashboard data |
| 166 | data := ds.collector.CollectDashboardData() |
| 167 | if jsonData, err := json.Marshal(data); err == nil { |
| 168 | conn.WriteMessage(websocket.TextMessage, jsonData) |
| 169 | } |
| 170 | |
| 171 | // Keep connection alive and handle pings |
| 172 | for { |
| 173 | _, _, err := conn.ReadMessage() |
| 174 | if err != nil { |
| 175 | if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { |
| 176 | shared.LogErrorf("WebSocket error: %v", err) |
| 177 | } |
| 178 | break |
| 179 | } |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | // startBroadcaster starts the background broadcaster for WebSocket updates |
| 184 | func (ds *DashboardServer) startBroadcaster() { |
nothing calls this directly
no test coverage detected