Files
seanime-docker/seanime-2.9.10/internal/handlers/websocket.go
2025-09-20 14:08:38 +01:00

95 lines
2.3 KiB
Go

package handlers
import (
"net/http"
"seanime/internal/events"
"github.com/goccy/go-json"
"github.com/gorilla/websocket"
"github.com/labstack/echo/v4"
)
var (
upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
)
// webSocketEventHandler creates a new websocket handler for real-time event communication
func (h *Handler) webSocketEventHandler(c echo.Context) error {
ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
if err != nil {
return err
}
defer ws.Close()
// Get connection ID from query parameter
id := c.QueryParam("id")
if id == "" {
id = "0"
}
// Add connection to manager
h.App.WSEventManager.AddConn(id, ws)
h.App.Logger.Debug().Str("id", id).Msg("ws: Client connected")
for {
_, msg, err := ws.ReadMessage()
if err != nil {
if websocket.IsCloseError(err, websocket.CloseNormalClosure) {
h.App.Logger.Debug().Str("id", id).Msg("ws: Client disconnected")
} else {
h.App.Logger.Debug().Str("id", id).Msg("ws: Client disconnection")
}
h.App.WSEventManager.RemoveConn(id)
break
}
event, err := UnmarshalWebsocketClientEvent(msg)
if err != nil {
h.App.Logger.Error().Err(err).Msg("ws: Failed to unmarshal message sent from webview")
continue
}
// Handle ping messages
if event.Type == "ping" {
timestamp := int64(0)
if payload, ok := event.Payload.(map[string]interface{}); ok {
if ts, ok := payload["timestamp"]; ok {
if tsFloat, ok := ts.(float64); ok {
timestamp = int64(tsFloat)
} else if tsInt, ok := ts.(int64); ok {
timestamp = tsInt
}
}
}
// Send pong response back to the same client
h.App.WSEventManager.SendEventTo(event.ClientID, "pong", map[string]int64{"timestamp": timestamp})
continue // Skip further processing for ping messages
}
h.HandleClientEvents(event)
// h.App.Logger.Debug().Msgf("ws: message received: %+v", msg)
// // Echo the message back
// if err = ws.WriteMessage(messageType, msg); err != nil {
// h.App.Logger.Err(err).Msg("ws: Failed to send message")
// break
// }
}
return nil
}
func UnmarshalWebsocketClientEvent(msg []byte) (*events.WebsocketClientEvent, error) {
var event events.WebsocketClientEvent
if err := json.Unmarshal(msg, &event); err != nil {
return nil, err
}
return &event, nil
}