htmgo/extensions/websocket/ws/handler.go

91 lines
2 KiB
Go
Raw Normal View History

2024-10-16 20:23:36 +00:00
package ws
2024-10-16 20:00:57 +00:00
import (
"fmt"
2024-10-16 20:23:36 +00:00
"github.com/maddalax/htmgo/extensions/ws/internal/wsutil"
"github.com/maddalax/htmgo/extensions/ws/state"
2024-10-16 20:00:57 +00:00
"sync"
)
type MessageHandler struct {
2024-10-16 20:23:36 +00:00
manager *wsutil.SocketManager
2024-10-16 20:00:57 +00:00
}
2024-10-16 20:23:36 +00:00
func NewMessageHandler(manager *wsutil.SocketManager) *MessageHandler {
2024-10-16 20:00:57 +00:00
return &MessageHandler{manager: manager}
}
func (h *MessageHandler) OnServerSideEvent(e ServerSideEvent) {
fmt.Printf("received server side event: %s\n", e.Event)
hashes, ok := serverEventNamesToHash.Load(e.Event)
// If we are not broadcasting to everyone, filter it down to just the current session that invoked the event
// TODO optimize this
if e.SessionId != "*" {
hashesForSession, ok2 := sessionIdToHashes.Load(e.SessionId)
if ok2 {
subset := make(map[KeyHash]bool)
for hash := range hashes {
if _, ok := hashesForSession[hash]; ok {
subset[hash] = true
}
}
hashes = subset
}
}
if ok {
lock.Lock()
callingHandler.Store(true)
wg := sync.WaitGroup{}
for hash := range hashes {
cb, ok := handlers.Load(hash)
if ok {
wg.Add(1)
go func(e ServerSideEvent) {
defer wg.Done()
sessionId, ok2 := hashesToSessionId.Load(hash)
if ok2 {
cb(HandlerData{
SessionId: sessionId,
Socket: h.manager.Get(string(sessionId)),
Manager: h.manager,
})
}
}(e)
}
}
wg.Wait()
callingHandler.Store(false)
lock.Unlock()
}
}
func (h *MessageHandler) OnClientSideEvent(handlerId string, sessionId state.SessionId) {
cb, ok := handlers.Load(handlerId)
if ok {
cb(HandlerData{
SessionId: sessionId,
Socket: h.manager.Get(string(sessionId)),
Manager: h.manager,
})
}
}
func (h *MessageHandler) OnDomElementRemoved(handlerId string) {
handlers.Delete(handlerId)
}
2024-10-16 20:23:36 +00:00
func (h *MessageHandler) OnSocketDisconnected(event wsutil.SocketEvent) {
2024-10-16 20:00:57 +00:00
sessionId := state.SessionId(event.SessionId)
hashes, ok := sessionIdToHashes.Load(sessionId)
if ok {
for hash := range hashes {
hashesToSessionId.Delete(hash)
handlers.Delete(hash)
}
sessionIdToHashes.Delete(sessionId)
}
}