Design and Implementation of a WebSocket Backend for a Real‑Time Multiplayer Quiz Game
This article details the design, architecture, and Java implementation of a WebSocket‑based backend that enables real‑time, multi‑player quiz battles, covering entity definitions, message handling, matchmaking logic, error handling, game flow, and supporting utilities such as Redis‑based state management.
The article introduces a real‑time interactive application where multiple users compete in a quiz battle, explaining why WebSocket’s full‑duplex communication is chosen over traditional HTTP polling to achieve low latency and persistent connections.
It describes a front‑back separation architecture: the front end uses JavaScript to connect to a Java‑based WebSocket server built with Spring, while the back end handles player matching, state synchronization, and game logic.
Technical details include state synchronization via broadcast messages, exception handling for abnormal disconnections, user status management (matching, in‑game, game‑over), and a dynamic queue matching algorithm that considers player rank.
Entity classes are defined to structure the communication payloads:
@Data
public class ChatMessage
{
private MessageTypeEnum type;
private String sender;
private Set
receivers;
private T data;
} public enum MessageTypeEnum {
MATCH_USER,
PLAY_GAME,
GAME_OVER,
} @Data
public class AnswerSituation {
private ArrayList
selfAnswerSituations;
} @Data
public class RoomAnswerSituation {
private String userId;
private String receiver;
private AnswerSituation selfAnswerSituations;
private AnswerSituation opponentAnswerSituations;
} @Data
public class UserMatchInfo {
private String userId;
private Integer score;
} @Data
public class GameMatchInfo {
private UserMatchInfo selfInfo;
private UserMatchInfo opponentInfo;
private List
questions;
private String selfUsername;
private String opponentUsername;
private String selfPicAvatar;
private String opponentPicAvatar;
}For error handling, a unified error‑code interface IServerError is defined, with GameServerError enum providing specific error codes, and GameServerException extending RuntimeException to encapsulate these errors.
The core WebSocket lifecycle methods are implemented with annotations:
@OnOpen
public void onOpen(@PathParam("userId") String userId, Session session) { ... } @OnError
public void onError(Session session, Throwable error) { ... } @OnClose
public void onClose() { ... } @OnMessage
public void onMessage(String message, Session session) { ... }Message handling branches based on MessageTypeEnum to perform player matching ( matchUser ), game progress updates ( toPlay ), and game termination ( gameover ). The matching logic uses a ReentrantLock and Condition to coordinate asynchronous matchmaking, stores player status in Redis via MatchCacheUtil , and ensures thread‑safe room allocation.
During gameplay, each answer submission updates the user’s score, records the selected answer in AnswerSituationUtil , and broadcasts the updated ScoreSelectedInfo to the opponent.
When the game ends, the winner’s ID is sent back, the server updates the user’s rating, and a RoomAnswerSituation containing both players’ answer histories is sent to both clients before cleaning up Redis entries and in‑memory caches.
Supporting configuration includes a WebsocketConfig class that registers the endpoint, and utility components for answer storage, user‑online status management, and Redis‑backed caches.
Overall, the article provides a comprehensive guide to building a robust, scalable WebSocket backend for real‑time multiplayer quiz applications using Java, Spring, Redis, and concurrent programming techniques.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.