diff --git a/app.go b/app.go index 446e526..3f3eb68 100644 --- a/app.go +++ b/app.go @@ -195,26 +195,31 @@ func (a *App) Cleanup() { // It cancels the context, closes the websocket connection, // and ensures all background processes are properly terminated. func (a *App) Close() error { + // Close websocket connection if it exists + if a.conn != nil { + deadline := time.Now().Add(10 * time.Second) + err := a.conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), deadline) + if err != nil { + slog.Warn("Error writing close message", "error", err) + return err + } + + // Close the websocket connection + err = a.conn.Close() + if err != nil { + slog.Warn("Error closing websocket connection", "error", err) + return err + } + } + + // Wait a short time for the websocket connection to close + time.Sleep(500 * time.Millisecond) + // Cancel context to signal all goroutines to stop if a.ctxCancel != nil { a.ctxCancel() } - // Close websocket connection if it exists - if a.conn != nil { - // Send close message to Home Assistant - closeMsg := map[string]string{ - "type": "close", - } - _ = a.conn.WriteJSON(closeMsg) - - // Close the websocket connection - err := a.conn.Close() - if err != nil { - slog.Warn("Error closing websocket connection", "error", err) - } - } - // Wait a short time for goroutines to finish // This allows for graceful shutdown of background processes time.Sleep(100 * time.Millisecond) @@ -373,7 +378,7 @@ func (a *App) Start() { } // entity listeners and event listeners - elChan := make(chan ws.ChanMsg) + elChan := make(chan ws.ChanMsg, 100) // Add buffer to prevent channel overflow go ws.ListenWebsocket(a.conn, elChan) for { diff --git a/internal/websocket/reader.go b/internal/websocket/reader.go index c15e138..06b70d7 100644 --- a/internal/websocket/reader.go +++ b/internal/websocket/reader.go @@ -50,7 +50,9 @@ func ListenWebsocket(conn *websocket.Conn, c chan ChanMsg) { // Message sent successfully default: // Channel is full or closed, break out of loop - slog.Warn("Websocket message channel is full or closed, stopping listener") + slog.Warn("Websocket message channel is full or closed, stopping listener", + "channel_capacity", cap(c), + "channel_length", len(c)) close(c) return }