WebSocket Protocol
The communication between the frontend (JS) and backend (Python) happens via JSON messages over WebSockets.
Endpoint: ws://<HOST>/ws/game/<ROOM_CODE>/
Client -> Server (Actions)
These messages are sent by the Frontend (Host or Player). Every message must have an action key.
Player Actions
| Action | Payload | Description |
|---|---|---|
join | {nickname: "Name", token: "UUID"} | Authenticates a player. Token is optional (for reconnects). |
answer | {option: "A"} | Submits an answer (A, B, C, or D). |
Game Master Actions
| Action | Payload | Description |
|---|---|---|
start_game | {} | Starts the first question of the quiz. |
next_question | {} | Advances to the next question. |
previous_question | {} | Go back one question. |
time_up | {} | Force stops the timer and reveals the result. |
control_timer | {command: "pause"} | Options: pause, add_10s, sub_10s. |
kick_player | {nickname: "User"} | Removes a player from the session. |
switch_quiz | {quiz_id: 1, reset_scores: true} | Injects a new quiz into the session. |
terminate_session | {} | Destroys the lobby and data. |
(See consumers.py for the full list of supported actions)
Server -> Client (Events)
These messages are broadcasted to connected clients. The type key indicates the event.
Global Events
| Type | Data | Description |
|---|---|---|
new_question | {question: {...}} | Displays a new question. Contains text, options, and duration. |
show_result | {correct_option: "A"} | Sent when time is up. Reveals the answer. |
game_over | {leaderboard: [...], is_intermediate: bool} | Sent when quiz ends. Shows final or intermediate rankings. |
timer_control | {command: "pause"} | Syncs timer state across devices. |
player_joined | {nickname: "Name"} | Sent to Host when a new player connects. |
session_terminated | {} | Redirects all users to the "Ended" screen. |
Private Events (Sent to specific socket)
| Type | Data | Description |
|---|---|---|
join_confirmed | {token: "UUID", ...} | Sent to player upon successful login. |
player_excluded | {message: "..."} | Sent if the player is excluded from the current question. |
error | {message: "..."} | Sent if an action failed (e.g., room full). |