Building a Realtime Leaderboard
In the world of gaming, leaderboards are a critical part of many real-time systems and are essential for tracking player rankings and improving engagement. DiceDB is a truly reactive database which allows you to eradicate the need to poll the database for changes by allowing clients to subscribe to changes in a sorted set (like a leaderboard). thus making it an excellent fit for implementing leaderboards. The goal of this example is to build a real-time leaderboard with DiceDB. We’ll walk through the process of creating a gaming leaderboard using sorted set commands and our DiceDB SDK.
But, before we start, make sure you have
- Go installed (at least version 1.18)
- Running instance of DiceDB
- Basic familiarity with DiceDB and its CLI
Environment setup
Starting DiceDB
Start the DiceDB server with the flag --enable-watch
to enable watch mode, respectively. Your command would look something
like this
Once the DiceDB server starts, you will see output similar to this
Starting the application server
- Clone the repository
- Start the application This will start the application server on port 8080 by default, you should see output similar to
Interacting with the application
- Navigate to the application server from your desired browser at http://localhost:8080.
- Update player with their respective scores.
- As more player with scores get added, we can see players getting ranked accordingly.
Key Components
- DiceDB: As the in-memory data store to realtime track user scores.
- DiceDB Go SDK: To allow interaction between application server and DiceDB.
ZRANGEWATCH
command: Allows the application to subscribe to changes in the leaderboard.ZADD
command: We’d leverage this command to add scores for users.- Websocket: To push real-time updates to connected users.
In this application, every player assigned with higher score is ranked at the top of leaderboard.
Understanding Real-Time Reactivity with ZRANGEWATCH
The ZRANGEWATCH
command allows the application to subscribe to changes in the leaderboard.
This allows users to eradicate the need to continuously poll the server as updates are automatically delivered whenever changes occur.
ZRANGEWATCH
only sends the relevant changes to clients, making the process highly efficient in terms of both bandwidth and processing power.
Flow of ZRANGEWATCH
:
- Setup: The client subscribes to updates on the leaderboard using
ZRANGEWATCH
. - Data Changes: Whenever a player’s score is updated, DiceDB triggers an update.
- Push Notifications: The server pushes the updated scores to all connected clients through WebSocket.
Code overview
-
WebSocket Handling: The code uses WebSocket to push real-time updates to connected users.
- This function establishes a WebSocket connection with clients. All connected clients are stored in connectedUsers.
- Once connected, clients will receive real-time updates whenever there is a change in the leaderboard.
-
Score Updates: The
handleUpdate
function processes incoming HTTP requests to update player scores.- This function receives a JSON payload with a player’s name and score, and then updates the leaderboard using
ZADD
command. - If the player already exists, their score is updated. Otherwise, a new player is added to the leaderboard.
- This function receives a JSON payload with a player’s name and score, and then updates the leaderboard using
-
Watch Loop: This is where the magic happens. The
watchLoop
function listens for updates from DiceDB and pushes them to all connected clients.- Watch Connection: A Watch Connection is established with DiceDB using WatchConn.
ZRANGEWATCH
: This command watches the top 5 scores of the leaderboard.- Real-Time Updates: Whenever there’s a change in the leaderboard, the watch channel(
watchCh
) receives an update, which is then broadcast to all connected clients via WebSocket.
Conclusion
DiceDB provides a powerful and efficient solution for implementing gaming leaderboards. By using DiceDB reactivity feature, you can create fast, scalable, and feature-rich leaderboards for your games, without having to
- periodically poll for the data, or
- knowing the internal data structures like Sorted Set.
Find the complete code for this example on Github.