nginx-proxy-manager/backend/internal/serverevents/sse.go
2023-07-28 15:01:54 +10:00

76 lines
1.8 KiB
Go

package serverevents
import (
"encoding/json"
"net/http"
"npm/internal/logger"
"github.com/jc21/go-sse"
)
var instance *sse.Server
const defaultChannel = "changes"
// Message is how we're going to send the data
type Message struct {
Lang string `json:"lang,omitempty"`
LangParams map[string]string `json:"lang_params,omitempty"`
Type string `json:"type,omitempty"`
Affects string `json:"affects,omitempty"`
}
// Get will return a sse server
func Get() *sse.Server {
if instance == nil {
instance = sse.NewServer(&sse.Options{
Logger: logger.Get(),
ChannelNameFunc: func(request *http.Request) string {
return defaultChannel // This is the channel for all updates regardless of visibility
},
})
}
return instance
}
// Shutdown will shutdown the server
func Shutdown() {
if instance != nil {
instance.Shutdown()
}
}
// SendChange will send a specific change
func SendChange(affects string) {
Send(Message{Affects: affects}, "")
}
// SendMessage will construct a message for the UI
func SendMessage(typ, lang string, langParams map[string]string) {
Send(Message{
Type: typ,
Lang: lang,
LangParams: langParams,
}, "")
}
// Send will send a message
func Send(msg Message, channel string) {
if channel == "" {
channel = defaultChannel
}
logger.Debug("SSE Sending: %+v", msg)
if data, err := json.Marshal(msg); err != nil {
logger.Error("SSEError", err)
} else {
Get().SendMessage(channel, sse.SimpleMessage(string(data)))
}
}
// TODO: if we end up implementing user visibility,
// then we'll have to subscribe people to their own
// channels and publish to all or some depending on visibility.
// This means using a specific ChannelNameFunc that revolves
// around the user and their visibility.