mirror of
https://github.com/tiennm99/260404.git
synced 2026-08-09 14:21:02 +00:00
Implement a real-time game server using protobuf over WebSocket: - Protobuf schema with 14 message types in oneof Envelope - Room-based lobby with join/leave/chat broadcast - ELO-based matchmaking with expanding range (±100 to ±500) - Turn-based game session lifecycle management - Multi-stage Docker build (Alpine) - Unit tests for matchmaking and game session logic
62 lines
1.4 KiB
Go
62 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"github.com/tiennm99/260404/internal/game"
|
|
"github.com/tiennm99/260404/internal/lobby"
|
|
"github.com/tiennm99/260404/internal/matchmaking"
|
|
"github.com/tiennm99/260404/internal/player"
|
|
"github.com/tiennm99/260404/internal/ws"
|
|
)
|
|
|
|
func main() {
|
|
addr := os.Getenv("ADDR")
|
|
if addr == "" {
|
|
addr = ":8080"
|
|
}
|
|
|
|
lobbyMgr := lobby.NewManager()
|
|
gameMgr := game.NewManager()
|
|
|
|
// Matchmaker callback: create a game session when players are matched.
|
|
onMatch := func(players []*player.Player, sessionID string) {
|
|
s := gameMgr.Create(sessionID, players)
|
|
s.BroadcastState()
|
|
log.Printf("match created: session=%s players=%d", sessionID, len(players))
|
|
}
|
|
|
|
mm := matchmaking.New(onMatch)
|
|
mm.Start()
|
|
defer mm.Stop()
|
|
|
|
wsHandler := ws.NewHandler(lobbyMgr, mm, gameMgr)
|
|
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/ws", wsHandler)
|
|
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte("ok"))
|
|
})
|
|
|
|
srv := &http.Server{Addr: addr, Handler: mux}
|
|
|
|
// Graceful shutdown.
|
|
go func() {
|
|
sigCh := make(chan os.Signal, 1)
|
|
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
|
<-sigCh
|
|
log.Println("shutting down...")
|
|
_ = srv.Close()
|
|
}()
|
|
|
|
log.Printf("game server listening on %s", addr)
|
|
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
|
log.Fatalf("server error: %v", err)
|
|
}
|
|
}
|