Fix: sse changes

This commit is contained in:
Grail Finder
2025-05-10 09:01:51 +03:00
parent 2f4891473b
commit 416cc63ec0
6 changed files with 44 additions and 31 deletions

View File

@ -4,7 +4,6 @@ import (
"fmt"
"log/slog"
"net/http"
"strings"
"time"
)
@ -73,18 +72,21 @@ func (broker *Broker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
messageChan := make(NotifierChan)
broker.newClients <- messageChan
defer func() { broker.closingClients <- messageChan }()
ctx := r.Context()
for {
event := <-messageChan
// // Proper SSE formatting
// fmt.Fprintf(w, "event: %s\n", event.EventName) // Event name line
// fmt.Fprintf(w, "data: %s\n\n", event.Payload) // Data line + empty line
// Alternative for multi-line data:
fmt.Fprintf(w, "event: %s\n", event.EventName)
for _, line := range strings.Split(event.Payload, "\n") {
fmt.Fprintf(w, "data: %s\n", line)
select {
case <-ctx.Done():
// Client disconnected
return
case event := <-messageChan:
_, err := fmt.Fprintf(w, "event: %s\ndata: %s\n\n", event.EventName, event.Payload)
if err != nil {
fmt.Println(err)
// Client disconnected
return
}
w.(http.Flusher).Flush()
}
fmt.Fprintf(w, "\n")
w.(http.Flusher).Flush()
}
}

View File

@ -1,4 +1,8 @@
{{define "main"}}
<div hx-ext="sse" sse-connect="/sub/sse" sse-swap="test">
Contents of this box will be updated in real time
with every SSE message received from the chatroom.
</div>
<!-- user has no username -> login form -->
{{ if not . }}
{{template "login"}}

View File

@ -78,6 +78,7 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) {
fi := &models.FullInfo{
State: userstate,
}
fi.List = listPublicRooms()
// save state to cache
if err := saveState(cleanName, userstate); err != nil {
// if err := saveFullInfo(fi); err != nil {

View File

@ -1,18 +1,22 @@
package handlers
import (
"fmt"
"golias/broker"
"golias/config"
"golias/pkg/cache"
"html/template"
"log/slog"
"net/http"
"os"
"time"
)
var (
log *slog.Logger
cfg *config.Config
memcache cache.Cache
Notifier *broker.Broker
)
func init() {
@ -22,6 +26,20 @@ func init() {
}))
memcache = cache.MemCache
cfg = config.LoadConfigOrDefault("")
Notifier = broker.NewBroker()
go Notifier.Listen()
ticker := time.NewTicker(2 * time.Second)
go func() {
counter := 0
for {
<-ticker.C
Notifier.Notifier <- broker.NotificationEvent{
EventName: "test",
Payload: fmt.Sprintf("%v test call of notifier", counter),
}
counter++
}
}()
}
var roundWords = map[string]string{
@ -69,10 +87,8 @@ func HandleHome(w http.ResponseWriter, r *http.Request) {
}
}
if fi != nil && fi.Room == nil {
log.Debug("loading list")
fi.List = listPublicRooms()
}
log.Debug("data debug", "fi", fi)
if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil {
log.Error("failed to exec templ;", "error", err, "templ", "base")
}

View File

@ -11,29 +11,16 @@ import (
"time"
)
// responseWriterWrapper wraps http.ResponseWriter to capture status code
type responseWriterWrapper struct {
http.ResponseWriter
status int
}
func (w *responseWriterWrapper) WriteHeader(status int) {
w.status = status
w.ResponseWriter.WriteHeader(status)
}
// LogRequests logs all HTTP requests with method, path and duration
func LogRequests(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// Wrap response writer to capture status code
ww := &responseWriterWrapper{ResponseWriter: w}
next.ServeHTTP(ww, r)
next.ServeHTTP(w, r)
duration := time.Since(start)
log.Debug("request completed",
"method", r.Method,
"path", r.URL.RequestURI(),
"status", ww.status,
"duration", duration.String(),
)
})

11
main.go
View File

@ -11,10 +11,11 @@ import (
func ListenToRequests(port string) error {
mux := http.NewServeMux()
server := &http.Server{
Handler: handlers.LogRequests(handlers.GetSession(mux)),
Addr: port,
ReadTimeout: time.Second * 5,
WriteTimeout: time.Second * 5,
Handler: handlers.LogRequests(handlers.GetSession(mux)),
Addr: port,
ReadTimeout: time.Second * 5,
// WriteTimeout: time.Second * 5,
WriteTimeout: 0, // sse streaming
}
fs := http.FileServer(http.Dir("assets/"))
mux.Handle("GET /assets/", http.StripPrefix("/assets/", fs))
@ -34,6 +35,8 @@ func ListenToRequests(port string) error {
mux.HandleFunc("GET /room/hideform", handlers.HandleHideCreateForm)
mux.HandleFunc("GET /word/show-color", handlers.HandleShowColor)
mux.HandleFunc("POST /check/name", handlers.HandleNameCheck)
// sse
mux.Handle("GET /sub/sse", handlers.Notifier)
slog.Info("Listening", "addr", port)
return server.ListenAndServe()
}