server_events/v2/middleware.go
2025-07-09 23:28:48 +02:00

84 lines
1.7 KiB
Go

package serverevents
import (
gocontext "context"
"fmt"
di "git.apihub24.de/admin/generic-di"
"github.com/coder/websocket"
"github.com/coder/websocket/wsjson"
"net/http"
"time"
)
func init() {
di.Injectable(newServerEventsMiddleware)
}
type MiddlewareOptions struct {
Path string
ContextLifetime time.Duration
KeepAliveTime time.Duration
}
type IMiddleware interface {
Use(options MiddlewareOptions, mux *http.ServeMux) *http.ServeMux
}
type serverEventsMiddleware struct {
hub IEventHub
}
func newServerEventsMiddleware() IMiddleware {
return &serverEventsMiddleware{
hub: di.Inject[IEventHub](),
}
}
func (middleware *serverEventsMiddleware) Use(options MiddlewareOptions, muxer *http.ServeMux) *http.ServeMux {
if muxer == nil {
muxer = http.NewServeMux()
}
eventHub := di.Inject[IEventHub]()
muxer.HandleFunc(options.Path, func(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if len(id) < 1 {
println(fmt.Sprintf("no id found in query websocket closed"))
return
}
c, connectionErr := websocket.Accept(w, r, nil)
if connectionErr != nil {
println(fmt.Sprintf("[Error on connect Websocket]: %v", connectionErr))
return
}
defer func() {
println("Websocket disconnect")
eventHub.OnDisconnected(id)
_ = c.CloseNow()
}()
eventHub.OnConnected(id, c)
for {
err := readMessage(c, eventHub, id)
if err != nil {
return
}
}
})
return muxer
}
func readMessage(c *websocket.Conn, eventHub IEventHub, id string) error {
var message Event
readErr := wsjson.Read(gocontext.Background(), c, &message)
if readErr != nil {
println(fmt.Sprintf("[Error on read from Websocket]: %v", readErr))
return readErr
}
eventHub.Event(message, id)
return nil
}