From 8c5eeeaa080929e00dce35525e8b849cf3e930b7 Mon Sep 17 00:00:00 2001 From: Derek Stevens Date: Sun, 27 Nov 2022 08:56:48 -0700 Subject: [PATCH] server, adapter: starting to put things together --- gametable/server.go | 50 +++++++++++++++++++++++++++++++++++++++------ mongodb/adapter.go | 23 +++++++++++++++++++-- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/gametable/server.go b/gametable/server.go index 9c65071..d6d2cc2 100644 --- a/gametable/server.go +++ b/gametable/server.go @@ -8,6 +8,9 @@ import ( "log" "net/http" "nhooyr.io/websocket" + "nilfm.cc/git/felt/dbengine" + "nilfm.cc/git/felt/models" + "nilfm.cc/git/quartzgun/cookie" "sync" "time" ) @@ -23,15 +26,17 @@ type GameTableServer struct { logf func(f string, v ...interface{}) serveMux http.ServeMux subscribersLock sync.Mutex - subscribers map[*Subscriber]struct{} + subscribers map[*Subscriber]models.tableKey + dbAdapter dbengine.DbAdapter } -func New() *GameTableServer { +func New(adapter dbengine.DbAdapter) *GameTableServer { srvr := &GameTableServer{ subscribeMessageBuffer: 16, logf: log.Printf, - subscribers: make(map[*Subscriber]struct{}), + subscribers: make(map[*Subscriber]models.TableKey{}), publishLimiter: rate.NewLimiter(rate.Every(time.Millisecond*100), 8), + dbAdapter: adapter, } srvr.serveMux.Handle("/", http.FileServer(http.Dir("./static"))) srvr.serveMux.HandleFunc("/subscribe", srvr.subscribeHandler) @@ -66,7 +71,8 @@ func (self *GameTableServer) subscribeHandler(w http.ResponseWriter, r *http.Req } } -func (self *GameTableServer) subscribe(ctx context.Context, c *websocket.Conn) error { +func (self *GameTableServer) subscribe(r *http.Request, c *websocket.Conn) error { + ctx := r.Context() ctx = c.CloseRead(ctx) s := &Subscriber{ @@ -75,8 +81,33 @@ func (self *GameTableServer) subscribe(ctx context.Context, c *websocket.Conn) e c.Close(websocket.StatusPolicyViolation, "connection too slow to keep up with messages") }, } + + tableName, tblNameErr := cookie.GetToken("tableName", r) + tablePasscode, tblPassErr := cookie.GetToken("tablePasscode", r) + + if tblNameErr != nil { + return tblNameErr + } else if tblPassErr != nil { + return tblPassErr + } + + tableKey = models.TableKey{ + Name: tableName, + Passcode: tablePasscode, + } + + if !self.dbAdapter.CheckTable(tableKey) { + return errors.New("Table with matching key was not found on this server") + } + self.addSubscriber(s) + defer self.deleteSubscriber(s) + select { + case s.msgs <- self.getCurrentState(tableKey): + default: + go s.closeSlow() + } for { select { @@ -125,9 +156,16 @@ func (self *GameTableServer) publish(msg []byte) { } } -func (self *GameTableServer) addSubscriber(s *Subscriber) { +func (self *GameTableServer) getCurrentState(tableKey models.TableKey) []byte { + // get diceroll log, map, and token state + // build into a []byte message + + return make([]byte, 1) +} + +func (self *GameTableServer) addSubscriber(s *Subscriber, k models.TableKey) { self.subscribersLock.Lock() - self.subscribers[s] = struct{}{} + self.subscribers[s] = k self.subscribersLock.Unlock() } diff --git a/mongodb/adapter.go b/mongodb/adapter.go index afd7a3f..e64fd04 100644 --- a/mongodb/adapter.go +++ b/mongodb/adapter.go @@ -20,6 +20,8 @@ type DbAdapter interface { CreateTable(table models.TableKey) error DestroyTable(table models.TableKey) error + CheckTable(table models.TableKey) boolean + InsertDiceRoll(table models.TableKey, diceRoll models.DiceRoll) error GetDiceRolls(table models.TableKey) ([]models.DiceRoll, error) @@ -38,7 +40,8 @@ type DbEngine struct { } func (self *DbEngine) mkCtx(timeoutSec int) context.Context { - return context.WithTimeout(context.Background(), 10*time.Second) + ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) + return ctx } func (self *DbEngine) Init(mongoUri string) error { @@ -47,7 +50,7 @@ func (self *DbEngine) Init(mongoUri string) error { return err } self.client = client - ctx, _ := self.mkCtx(10) + ctx := self.mkCtx(10) err = client.Connect(ctx) if err != nil { @@ -114,6 +117,22 @@ func (self *DbEngine) DestroyTable(table models.TableKey) error { return errors.New(fmt.Sprintf(errNoCollection, "tables")) } +func (self *DbEngine) CheckTable(table models.TableKey) boolean { + tables := self.db.Collection("tables") + if tables != nil { + _, err := tables.FindOne(self.mkCtx(10), bson.D{ + {"name", table.Name}, + {"passcode", table.Passcode}, + }) + if err != nil { + return false + } else { + return true + } + } + return false +} + func (self *DbEngine) InsertDiceRoll(table models.TableKey, diceRoll models.DiceRoll) error { tables := self.db.Collection("tables") if tables != nil {