From 6926aa42ad74c664c07b07ed1871eff572ef92ec Mon Sep 17 00:00:00 2001 From: Patrick Fairbank Date: Fri, 23 Aug 2019 22:03:07 -0700 Subject: [PATCH] Add arena status websocket API for clients that need realtime match signaling. --- web/api.go | 18 ++++++++++++++++++ web/api_test.go | 18 ++++++++++++++++++ web/setup_led_plc.go | 2 +- web/web.go | 1 + 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/web/api.go b/web/api.go index fe63a48..dfbce92 100644 --- a/web/api.go +++ b/web/api.go @@ -9,6 +9,7 @@ import ( "encoding/json" "github.com/Team254/cheesy-arena/game" "github.com/Team254/cheesy-arena/model" + "github.com/Team254/cheesy-arena/websocket" "github.com/gorilla/mux" "net/http" ) @@ -176,3 +177,20 @@ func (web *Web) alliancesApiHandler(w http.ResponseWriter, r *http.Request) { return } } + +// Websocket API for receiving arena status updates. +func (web *Web) arenaWebsocketApiHandler(w http.ResponseWriter, r *http.Request) { + if !web.userIsAdmin(w, r) { + return + } + + ws, err := websocket.NewWebsocket(w, r) + if err != nil { + handleWebErr(w, err) + return + } + defer ws.Close() + + // Subscribe the websocket to the notifiers whose messages will be passed on to the client. + ws.HandleNotifiers(web.arena.MatchTimingNotifier, web.arena.MatchLoadNotifier, web.arena.MatchTimeNotifier) +} diff --git a/web/api_test.go b/web/api_test.go index 70cca40..86f1e45 100644 --- a/web/api_test.go +++ b/web/api_test.go @@ -7,6 +7,8 @@ import ( "encoding/json" "github.com/Team254/cheesy-arena/game" "github.com/Team254/cheesy-arena/model" + "github.com/Team254/cheesy-arena/websocket" + gorillawebsocket "github.com/gorilla/websocket" "github.com/stretchr/testify/assert" "testing" "time" @@ -123,3 +125,19 @@ func TestAlliancesApi(t *testing.T) { } } } + +func TestArenaWebsocketApi(t *testing.T) { + web := setupTestWeb(t) + + server, wsUrl := web.startTestServer() + defer server.Close() + conn, _, err := gorillawebsocket.DefaultDialer.Dial(wsUrl+"/api/arena/websocket", nil) + assert.Nil(t, err) + defer conn.Close() + ws := websocket.NewTestWebsocket(conn) + + // Should get a few status updates right after connection. + readWebsocketType(t, ws, "matchTiming") + readWebsocketType(t, ws, "matchLoad") + readWebsocketType(t, ws, "matchTime") +} diff --git a/web/setup_led_plc.go b/web/setup_led_plc.go index 4f46f10..4b156a6 100644 --- a/web/setup_led_plc.go +++ b/web/setup_led_plc.go @@ -49,6 +49,6 @@ func (web *Web) ledPlcWebsocketHandler(w http.ResponseWriter, r *http.Request) { } defer ws.Close() - // Subscribe the websocket to the notifiers whose messages will be passed on to the client, in a separate goroutine. + // Subscribe the websocket to the notifiers whose messages will be passed on to the client. ws.HandleNotifiers(web.arena.Plc.IoChangeNotifier) } diff --git a/web/web.go b/web/web.go index ac6939a..a3f600c 100644 --- a/web/web.go +++ b/web/web.go @@ -102,6 +102,7 @@ func (web *Web) newHandler() http.Handler { router.HandleFunc("/alliance_selection/reset", web.allianceSelectionResetHandler).Methods("POST") router.HandleFunc("/alliance_selection/start", web.allianceSelectionStartHandler).Methods("POST") router.HandleFunc("/api/alliances", web.alliancesApiHandler).Methods("GET") + router.HandleFunc("/api/arena/websocket", web.arenaWebsocketApiHandler).Methods("GET") router.HandleFunc("/api/matches/{type}", web.matchesApiHandler).Methods("GET") router.HandleFunc("/api/rankings", web.rankingsApiHandler).Methods("GET") router.HandleFunc("/api/sponsor_slides", web.sponsorSlidesApiHandler).Methods("GET")