@@ -35,12 +35,22 @@ func (wd *WebDashboard) handleWebSocket(w http.ResponseWriter, r *http.Request)
3535 wd .sendMetricsToConnection (conn )
3636
3737 // Clean up when connection closes
38- wd .wsMutex .Lock ()
39- delete (wd .wsConnections , conn )
40- delete (wd .wsWriteMutexes , conn )
41- wd .wsMutex .Unlock ()
38+ defer func () {
39+ wd .wsMutex .Lock ()
40+ delete (wd .wsConnections , conn )
41+ delete (wd .wsWriteMutexes , conn )
42+ wd .wsMutex .Unlock ()
43+ log .Printf ("WebSocket connection closed from %s" , r .RemoteAddr )
44+ }()
45+
46+ // Start message handler in goroutine
47+ go wd .handleWebSocketMessages (conn )
4248
43- log .Printf ("WebSocket connection closed from %s" , r .RemoteAddr )
49+ // Start keepalive in goroutine
50+ go wd .keepConnectionAlive (conn )
51+
52+ // Wait for connection to close
53+ select {}
4454}
4555
4656// handleWebSocketMessages processes incoming WebSocket messages
@@ -109,7 +119,7 @@ func (wd *WebDashboard) handleWebSocketCommand(conn *websocket.Conn, cmd map[str
109119func (wd * WebDashboard ) handleSubscription (conn * websocket.Conn , cmd map [string ]interface {}) {
110120 // Future enhancement: Allow clients to subscribe to specific metrics
111121 log .Printf ("WebSocket subscription request: %v" , cmd )
112- }
122+
113123
114124// keepConnectionAlive maintains WebSocket connection with ping/pong
115125func (wd * WebDashboard ) keepConnectionAlive (conn * websocket .Conn ) {
@@ -143,6 +153,25 @@ func (wd *WebDashboard) handleUnsubscription(conn *websocket.Conn, cmd map[strin
143153 log .Printf ("WebSocket unsubscription request: %v" , cmd )
144154}
145155
156+ // buildMetricsMessage creates a metrics message with current dashboard data
157+ func (wd * WebDashboard ) buildMetricsMessage () map [string ]interface {} {
158+ wd .mu .RLock ()
159+ metrics := DashboardMetrics {
160+ Timestamp : time .Now (),
161+ GPUMetrics : wd .lastMetrics ,
162+ SystemStats : wd .calculateSystemStats (),
163+ CostData : wd .lastCostData ,
164+ Alerts : wd .getActiveAlerts (),
165+ Performance : wd .calculatePerformanceMetrics (),
166+ }
167+ wd .mu .RUnlock ()
168+
169+ return map [string ]interface {}{
170+ "type" : "metrics_update" ,
171+ "data" : metrics ,
172+ }
173+ }
174+
146175// broadcastToAllConnections sends a message to all connected WebSocket clients
147176func (wd * WebDashboard ) broadcastToAllConnections (message interface {}) {
148177 wd .wsMutex .RLock ()
0 commit comments