playback-device-server/server/websocket_server.go

73 lines
1.6 KiB
Go

package server
import (
"encoding/json"
"github.com/gorilla/websocket"
"github.com/labstack/echo/v4"
)
var upgrader = websocket.Upgrader{}
type WebsocketHandler interface {
Handle(message map[string]any, senderId string, sockets map[string]*websocket.Conn)
}
type WebsocketServer struct {
router *echo.Echo
sockets map[string]*websocket.Conn
handlers []WebsocketHandler
}
func (s *WebsocketServer) Initialize(authenticator *Authenticator) {
s.sockets = make(map[string]*websocket.Conn)
s.router.Use(authenticator.Authenticate("/ws", []string{}))
s.router.GET("/ws", s.handle)
}
func (s *WebsocketServer) handle(context echo.Context) error {
authContext := context.(AuthContext)
senderId := getAuthenticatedId(authContext)
ws, err := upgrader.Upgrade(context.Response(), context.Request(), nil)
s.sockets[senderId] = ws
if err != nil {
return err
}
defer func() {
ws.Close()
delete(s.sockets, senderId)
}()
for {
messageType, messageBytes, err := ws.ReadMessage()
if err != nil {
return err
}
if messageType == websocket.TextMessage {
var messageObject map[string]any
json.Unmarshal(messageBytes, &messageObject)
for _, handler := range s.handlers {
handler.Handle(messageObject, senderId, s.sockets)
}
}
}
}
func getAuthenticatedId(authContext AuthContext) string {
if authContext.User != nil {
return authContext.User.ID
}
if authContext.Integration != nil {
return authContext.Integration.ID
}
return ""
}
func (s *WebsocketServer) AddHandler(handler WebsocketHandler) {
s.handlers = append(s.handlers, handler)
}
func (s *WebsocketServer) SetRouter(router *echo.Echo) {
s.router = router
}