refactor pushing state over websocket into a func

main
Bel LaPointe 2024-12-15 11:24:32 -07:00
parent 74a403fa6d
commit 64165c5745
1 changed files with 129 additions and 111 deletions

View File

@ -17,27 +17,50 @@ func isWS(r *http.Request) bool {
return r.URL.Path == "/ws" || strings.HasPrefix(r.URL.Path, "/ws/") return r.URL.Path == "/ws" || strings.HasPrefix(r.URL.Path, "/ws/")
} }
func (s *S) serveWS(w http.ResponseWriter, r *http.Request) error { type WS struct {
ctx, can := context.WithCancel(r.Context()) *S
defer can() c *websocket.Conn
}
func (s *S) serveWS(w http.ResponseWriter, r *http.Request) error {
c, err := websocket.Accept(w, r, nil) c, err := websocket.Accept(w, r, nil)
if err != nil { if err != nil {
return err return err
} }
defer c.CloseNow() defer c.CloseNow()
ws := WS{S: s, c: c}
return ws.serve(w, r)
}
ugs, err := NewUserGameServer(ctx, s.Session(ctx), s.games) func (ws WS) serve(w http.ResponseWriter, r *http.Request) error {
ctx, can := context.WithCancel(r.Context())
defer can()
r = r.WithContext(ctx)
ugs, err := ws.newUserGameServer(ctx)
if err != nil { if err != nil {
return err return err
} }
go ugs.Listen(ctx, can, func(ctx context.Context) ([]byte, error) { go ugs.Listen(ctx, can, func(ctx context.Context) ([]byte, error) {
_, b, err := c.Read(ctx) _, b, err := ws.c.Read(ctx)
return b, err return b, err
}) })
for ugs.More(ctx) == nil { for ugs.More(ctx) == nil {
if err := ws.Push(ctx, ugs); err != nil {
return err
}
}
return ctx.Err()
}
func (ws WS) newUserGameServer(ctx context.Context) (*UserGameServer, error) {
return NewUserGameServer(ctx, ws.Session(ctx), ws.games)
}
func (ws WS) Push(ctx context.Context, ugs *UserGameServer) error {
gameState, err := ugs.State(ctx) gameState, err := ugs.State(ctx)
if err != nil { if err != nil {
return err return err
@ -61,17 +84,17 @@ func (s *S) serveWS(w http.ResponseWriter, r *http.Request) error {
msg["event"] = "A" msg["event"] = "A"
items := []map[string]any{} items := []map[string]any{}
for k, v := range gameState.Players { for k, v := range gameState.Players {
if k == s.Session(ctx).ID { if k == ws.Session(ctx).ID {
continue continue
} }
name, err := s.games.UserName(ctx, k) name, err := ws.games.UserName(ctx, k)
if err != nil { if err != nil {
return err return err
} }
tags := []map[string]any{} tags := []map[string]any{}
if self := gameState.Players[s.Session(ctx).ID]; self.KillWords.Assignee == k { if self := gameState.Players[ws.Session(ctx).ID]; self.KillWords.Assignee == k {
for _, private := range v.KillWords.Assignment.Private { for _, private := range v.KillWords.Assignment.Private {
tags = append(tags, map[string]any{ tags = append(tags, map[string]any{
"k": private.Word, "k": private.Word,
@ -85,7 +108,7 @@ func (s *S) serveWS(w http.ResponseWriter, r *http.Request) error {
"v": public.Points, "v": public.Points,
}) })
} }
if self := gameState.Players[s.Session(ctx).ID]; !slices.ContainsFunc(self.Kills, func(a Kill) bool { if self := gameState.Players[ws.Session(ctx).ID]; !slices.ContainsFunc(self.Kills, func(a Kill) bool {
return a.Victim == k return a.Victim == k
}) { }) {
tags = append(tags, map[string]any{ tags = append(tags, map[string]any{
@ -110,7 +133,7 @@ func (s *S) serveWS(w http.ResponseWriter, r *http.Request) error {
msg["event"] = "B" msg["event"] = "B"
items := []map[string]any{} items := []map[string]any{}
for k, v := range gameState.Players { for k, v := range gameState.Players {
name, err := s.games.UserName(ctx, k) name, err := ws.games.UserName(ctx, k)
if err != nil { if err != nil {
return err return err
} }
@ -133,7 +156,7 @@ func (s *S) serveWS(w http.ResponseWriter, r *http.Request) error {
msg["page"] = "A" msg["page"] = "A"
items := []map[string]any{} items := []map[string]any{}
for k := range gameState.Players { for k := range gameState.Players {
name, err := s.games.UserName(ctx, k) name, err := ws.games.UserName(ctx, k)
if err != nil { if err != nil {
return err return err
} }
@ -143,10 +166,5 @@ func (s *S) serveWS(w http.ResponseWriter, r *http.Request) error {
} }
msgB, _ := json.Marshal(msg) msgB, _ := json.Marshal(msg)
if err := c.Write(ctx, 1, msgB); err != nil { return ws.c.Write(ctx, 1, msgB)
return err
}
}
return ctx.Err()
} }