Code structure
Last updated
Last updated
In this guide you will learn how InstaQuiz server works and how you can extend it for your own usage.
The application uses Express.Js, Postgresql in the server and Socket.IO on both ends for real-time synchronization between users in a game room.
Users, questions and game creation are handled by REST API using express routers.
And actions related to real-time running of the game such as sending game info to all users in game, receiving answers and updating leaderboard, starting the game loop and syncing questions for all users are handled by Socket.IO event handlers.
For lowest latency while the game loop is running game info and game leaderboard are cached with that is an in memory key-value caching library
Game has 3 statuses:
0 = Created
1 = Running
2 = Ended
Each game contains 10 questions that are randomly selected based on the category selected by the user while creating the game.
Anyone with the link to the game can join and if users lose connection or crash can rejoin if the game is still running.
Users can see who is in the game before joining if the game is ended the results will be displayed instead.
Each question has 20 seconds timeout and if the user answers in the first 6 seconds they will receive the complete score that is 10 and after that each if they answered from 7 to 16 seconds their score is lowered by 1 each 2 seconds and from 17 to 20 by each second delayed, the code for this logic is located at ./server/src/events/answer.ts
The main entry for the application is located at ./server/src/app.js and it will be run when the app starts and sets up an Express.Js app, it's middlewares, routes, Socket.io events handler and event emitters.
Event structure
Each event is a function that takes a socket param as entry that receives events
and can have 3 different optional functions as parameters for emitting events to users:
updateWaitList
updateGameInfo
updateLeaderboard
functions receive gameId as parameter and have an optional parameter for getting data from cache.
A socket event handler can have below structure:
Listens to getWaitList
event from socket.
gameId
If game was ended it returns the leaderboard if not returns the list of users present in game.
Path: ./server/src/events/waitlist.ts
Listens to joinGame
event from socket.
Input parameters
userId
gameId
Path: ./server/src/events/join.ts
Listens to gameAnswer
socket event.
Input parameters:
gameId
userId
questionId
answerId
isCorrect
Path: ./server/src/events/answer.ts
Listens to startGame
socket event.
Input parameters:
userId
gameId
If the game has not started it will be updated in the database, game info and leaderboard will be retrieved from the database, game loop starts and returns current data to the user who started the game.
Game loop emits questions each 15 seconds using timeout and all data is handled by cache the time of game running to ensure there is no delay.
If game was ended return error and if it was not the creator of the game add user to table cache leaderboard, return gameInfo and leaderboard.
Get user answer, calculate score from game field and save to database.