feat: stream room updates SSE endpoint
via subscription to redis with enriched channel
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
"strings"
|
||||
|
||||
"sunshine.industries/some-automoderation/rooms"
|
||||
"sunshine.industries/some-automoderation/sessions"
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
|
||||
const roomPath = "/room/"
|
||||
const raiseHandPath = "/rooms/raise/"
|
||||
const subscribeRoomPath = "/rooms/subscribe"
|
||||
|
||||
// registering all routes for page and logic of /room/:roomName
|
||||
func registerPageRoutes(
|
||||
@@ -24,8 +25,6 @@ func registerPageRoutes(
|
||||
sessionSM sessions.SessionManagement,
|
||||
roomsM rooms.RoomManager,
|
||||
) {
|
||||
http.HandleFunc("/rooms/random", streamingBsRoute())
|
||||
|
||||
http.Handle(roomPath, // ending in / captures all following path sections, i.e room name
|
||||
authedPageMiddleware(
|
||||
sessionSM,
|
||||
@@ -35,36 +34,65 @@ func registerPageRoutes(
|
||||
authedPageMiddleware(
|
||||
sessionSM,
|
||||
http.StripPrefix(raiseHandPath, raiseGestureHandRoute(templateFs, roomsM))))
|
||||
|
||||
http.Handle(subscribeRoomPath,
|
||||
authedPageMiddleware(
|
||||
sessionSM,
|
||||
http.StripPrefix(subscribeRoomPath, streamingRoomStates(templateFs, roomsM))))
|
||||
}
|
||||
|
||||
func streamingBsRoute() http.HandlerFunc {
|
||||
func streamingRoomStates(
|
||||
templateFs *embed.FS,
|
||||
roomsM rooms.RoomManager,
|
||||
) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
queryParam := r.FormValue("mobile")
|
||||
roomName := r.FormValue("roomName")
|
||||
defer log.Printf("/rooms/subscribe/%s stream ended\n", roomName)
|
||||
|
||||
session, found := getContextSession(r.Context())
|
||||
if !found {
|
||||
log.Printf("/rooms/raiseGesture session not found, should be impossible")
|
||||
// TODO return error i guess
|
||||
return
|
||||
}
|
||||
if session.RoomId != roomName {
|
||||
// not authorized
|
||||
log.Printf("/rooms/streamingRoom got unauth with session.RoomId (%s) != roomName (%s)", session.RoomId, roomName)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
log.Printf("Starting stream for room %s for %d\n", roomName, session.PersonId)
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("Connection", "keep-alive")
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
startTime, endTime := 0, 0
|
||||
for {
|
||||
select {
|
||||
case <-r.Context().Done():
|
||||
log.Printf("canlecced streaming!")
|
||||
return
|
||||
default:
|
||||
log.Printf("another step in streaming bs")
|
||||
data := "data: <div>hello with data %d! waited %d. mobile is %s</div> \n\n"
|
||||
startTime = time.Now().Nanosecond()
|
||||
diff := endTime - startTime
|
||||
fmt.Fprintf(w, data, rand.Intn(100), diff, queryParam)
|
||||
w.(http.Flusher).Flush()
|
||||
time.Sleep(3 * time.Second)
|
||||
endTime = time.Now().Nanosecond()
|
||||
|
||||
templFile := "templates/room.gohtml"
|
||||
tmpl := template.Must(template.ParseFS(templateFs, templFile))
|
||||
|
||||
roomStream := roomsM.Subscribe(r.Context(), roomName)
|
||||
for room := range roomStream {
|
||||
// log.Printf("/rooms/streamingRoom iterating with %+v", room)
|
||||
fmt.Fprint(w, "data: ")
|
||||
|
||||
var buffer bytes.Buffer
|
||||
|
||||
err := tmpl.ExecuteTemplate(&buffer, "simpleRoomShow", room)
|
||||
if err != nil {
|
||||
log.Printf("/rooms/subscribe/%s got error on template %s", roomName, err)
|
||||
}
|
||||
|
||||
templateStr := buffer.String()
|
||||
templateLine := strings.ReplaceAll(templateStr, "\n", "")
|
||||
fmt.Fprint(w, templateLine)
|
||||
|
||||
fmt.Fprint(w, "\n\n")
|
||||
w.(http.Flusher).Flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if currently speaking? i guess first lower the hand and then raise new
|
||||
// if currently speaking? i guess first lower the hand and then raise new
|
||||
func raiseGestureHandRoute(
|
||||
templateFs *embed.FS,
|
||||
roomsM rooms.RoomManager,
|
||||
@@ -131,6 +159,14 @@ func roomPageRoute(
|
||||
return
|
||||
}
|
||||
|
||||
room, found, err := roomsM.Get(roomName)
|
||||
if err != nil || !found {
|
||||
log.Printf("/room room for name %s not found or err: %s / found %d", roomName, err, found)
|
||||
// TODO here should be append to error place
|
||||
w.Header().Add("HX-Redirect", "/")
|
||||
return
|
||||
}
|
||||
|
||||
// now we should have a session for this specific room
|
||||
fmt.Printf("all checks for room %s passed with %+v", roomName, session)
|
||||
|
||||
@@ -150,14 +186,14 @@ func roomPageRoute(
|
||||
}
|
||||
|
||||
pageData := struct {
|
||||
RoomName string
|
||||
Room rooms.Room
|
||||
Gestures []GestureData
|
||||
}{
|
||||
RoomName: roomName,
|
||||
Room: room,
|
||||
Gestures: gesturesData,
|
||||
}
|
||||
|
||||
err := tmpl.Execute(w, pageData)
|
||||
err = tmpl.Execute(w, pageData)
|
||||
if err != nil {
|
||||
log.Printf("/room/%s my error in executing template, huh\n %s", roomName, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user