Replace polling loop with NATS pub/sub for game updates

Use via's embedded NATS server to notify players of state changes
instead of a 100ms polling ticker. Each player subscribes to
"game.<id>" on page load; via auto-cleans subscriptions on disconnect,
eliminating the need for manual player tracking and RegisterSync.
This commit is contained in:
Ryan Hamamura
2026-01-31 10:26:31 -10:00
parent d079b90a33
commit a6b5a46a8a
5 changed files with 86 additions and 96 deletions

19
main.go
View File

@@ -15,6 +15,7 @@ import (
"github.com/ryanhamamura/c4/ui"
"github.com/ryanhamamura/via"
"github.com/ryanhamamura/via/h"
"github.com/ryanhamamura/via/vianats"
)
var store = game.NewGameStore()
@@ -43,12 +44,20 @@ func main() {
log.Fatal(err)
}
ctx := context.Background()
ns, err := vianats.New(ctx, "./data/nats")
if err != nil {
log.Fatal(err)
}
store.SetPubSub(ns)
v := via.New()
v.Config(via.Options{
LogLevel: via.LogLevelDebug,
DocumentTitle: "Connect 4",
ServerAddress: ":7331",
SessionManager: sessionManager,
PubSub: ns,
Plugins: []via.Plugin{DaisyUIPlugin},
})
@@ -307,7 +316,6 @@ func main() {
}
gi.Join(&game.PlayerSession{
Player: player,
Sync: c,
})
}
c.Sync()
@@ -336,6 +344,11 @@ func main() {
}
})
// Subscribe to game updates so the opponent's moves trigger a re-render
if gameExists {
c.Subscribe("game."+gameID, func(data []byte) { c.Sync() })
}
// If nickname exists in session and game exists, join immediately
if gameExists && sessionNickname != "" && gi.GetPlayerColor(playerID) == 0 {
player := &game.Player{
@@ -347,11 +360,7 @@ func main() {
}
gi.Join(&game.PlayerSession{
Player: player,
Sync: c,
})
} else if gameExists && gi.GetPlayerColor(playerID) != 0 {
// Re-register sync context for existing players on reconnect
gi.RegisterSync(playerID, c)
}
c.View(func() h.H {