The server that handles client requests and communicates with databases and kafka
The Join Game endpoint will take from the url query parameter () the team it is joining.
This connection will then be upgraded into a websocket via request by this server. This establishes the connection.
The endpoint should be formatted like such ws://<url>/joinGame (TODO finish query parameter)
This can be tested locally by using the Chrome Extension. Note: the messages must be in json format according to the models.Message object
There are two types of messages communicated via websocket.
A GraphUpdate is sent to the WebApp in order to update the current state of the graph.
-
NewNode represents the new node to be added to the graph
-
ConnectingNode represents the node that the NewNode is connected to
- If ConnectingNode is nil, this is the root node
-
Guess represents what was guessed for updating the list of guesses
-
Correct represents whether or not the guess was correct
- if correct false, only Guess will be populated
-
Good Example
{
"guess" : "Peter Parker",
"correct" : true,
"newNodeId" : 23,
"newNodeText" : "Peter Parker",
"connectingNodeId" : 2,
"connectingNodeText" : "Spider-man",
"undiscoveredNodes" : 3
}- Bad Example
{
"guess" : "Peter Parked",
"correct" : false,
"newNodeId" : -1,
"newNodeText" : "",
"connectingNodeId" : -1,
"connectingNodeText" : "",
"undiscoveredNodes" : 0
}The second type of message is a WordGuess. This is used when a user wants to guess a word and is sent from the WebApp to the server and back.
- guess is a string of what the user wanted to guess
{
"guess" : "Toby"
}AdminpPassword: <string>
Content-Type: application/json
Note: Not all endpoints require the AdminPassword header, below it will specify
{
"field" : value
}{
"data" : {},
"error" : {},
"success" : false
}Note: the data and error could be any number of objects, they are stored as
interface{}types in go
Used to get all games with specified fields for each game
/listGames?fields=name,gameID,startNode
fieldsNote: Possible fields include
name,gameID,startNode,timeLimit,teams,status, andstartTime
{
"data" : [
{
"gameID":"gameID",
"name":"gameName",
"startNode":"startNodeID",
"timeLimit":100000,
"status":"in-progress",
"startTime":1556987407,
"teams": [
{
"teamID":"teamID",
"name":"teamName",
"score":0
}
]
}
],
"error" : null,
"success" : true
}Similar to ListGames except only fetches info for the provided gameID
/gameInfo?gameID=<gameID>&fields=name,timeLimit,teams
fields
gameIDNote: Possible fields include
name,gameID,startNode,timeLimit,teams,status, andstartTime
{
"data" :
{
"gameID":"gameID",
"name":"gameName",
"startNode":"startNodeID",
"timeLimit":100000,
"status":"in-progress",
"startTime":1556987407,
"teams": [
{
"teamID":"teamID",
"name":"teamName",
"score":0
}
]
},
"error" : null,
"success" : true
}Similar to ListGames except gets all Teams
/listTeams
{
"data" : [
{
"teamID":"teamID",
"name":"teamName",
"score":0
}
],
"error" : null,
"success" : true
}Similar to ListTeams except for only for the given teamID
/teamInfo?teamID=<teamID>
teamID{
"data" : {
"teamID":"teamID",
"name":"teamName",
"score":0
},
"error" : null,
"success" : true
}Create a game with the provided information, returns the new game's gameID
/createGame
AdminpPassword: <string>
{
"name": "game-name",
"timeLimit": 1000,
"teams": ["team1", "team2", "team3"]
}{
"data" : {
"gameID": "gameID"
},
"error" : null,
"success" : true
}Starts the game of the given gameID in the query parameters
/startGame?gameID=1
AdminpPassword: <string>
gameID int{
"data" : "Started Game 1",
"error" : null,
"success" : true
}WIP
Returns a websocket for communicating game state and player actions
/joinGame?gameID=<gameID>
{
"data" : {},
"error" : {},
"success" : false
}/adminCheck
AdminpPassword: <string>
{}{
"data" : null,
"error" : null,
"success" : true
}/deleteGame?gameID=<gameID>
AdminpPassword: <string>
{}{
"data" : null,
"error" : null,
"success" : true
}There are a handful of things we need to keep track of, especially since we strive to keep the application stateless.
There are two categories of data we want to store in Redis, game metadata and the edge nodes for a team's graph
We need to store:
- An ID or lobby name
- Team ids (rather than team names, teams will be under a hash)
- status: waiting, in-progress, complete
- time duration
- start node id
- start time if in-progress
We could potentially use a zset and unix time to show either most recent games or oldest games first We can also make unique id's by having a count variable in redis and incrementing it, one for each type maybe
We don't really need to keep track of individual players if we use the Kafka well, we can simply track team progress
We need to store:
- Name
- Score (might have game thread increment this stuff)
UUID variables
game:id string // technically can be int, look at redis STRING type
team:id string
Games
gameID = <number>
game:gameID field value
games [gameID1key, gameID2key] // a set of gameIDs, easier when getting all games
game:gameID gameID string
game:gameID name string
game:gameID teamIDs []intToJSONString // I'll just use a json string
game:gameID timeLimit string
game:gameID startNode string
game:gameID status string // waiting, in-progress, complete
game:gameID startTime string // 0 if not in progress
Teams
teamID = <number>
team:teamID field value
team:teamID teamID string
team:teamID name string
team:teamID score int