Websockets¶
Overview¶
This section shows the communication protocol between a client and the websocket server. The possible messages are related to the game phase and to
the role
of the client in the match. The client must be authenticated to communicate with the server.
Protocol description¶
Connection phase¶
First of all, the client should start the communication with the server. In this phase the user must specify the role and the id
of the match to join.
In order to start the communication, the client must open a websocket connection using the following url:
ws://HOST:PORT/ws/game/{match_id}/?role={role}
The connection may be rejected due to several errors described below.
Role independent errors
The match ID does not exist:
{"error": "non existent requested match", "code": 5}
The user is not authenticated:
{"error": "unauthenticated user, please send auth token", "code": 6}
The query string contains more than one parameter or is not well formed:
{"error": "bad key in query string. expected: role", "code": 7}
The requested role is not in [host, challenger, spectator]
:
{"error": "bad value in query string. expected: [spectator, host, challenger]", "code": 7}
Challenger or spectator related error
The client requested to be a spectator or a challenger but the user is already in a match or the match is full:
{"error": "trying to join a match while already in another match or the match is full", "code": 9}
Host related error
The client requested to be an host of a match different from the one already hosted:
{"error": "trying to join a match as host which you did not start", "code": 8}
Success
Finally, if everything is ok for the server, the connection is established, and the client receives:
{"status": "success", "code": 0}
From now on the websocket server can receive different type of commands
from its client. If the requested role is spectator
,
the websocket server will ignore all the commands coming from that user.
Game initialization phase¶
After having established the connection with the websocket server for a specific ongoing match, it is time to start the game. The host of the match is responsible for starting the match. A match can start only if a challenger is present and is ready to play.
Role independent error
If a client sends a message without the command
keyword, the websocket server will always answer as below:
{"error": "no command sent", "code": 2}
Challenger ready
A challenger in order to communicate that is ready to play must send the following command:
{"command": "ready"}
From this moment, until the match begins, all commands sent from the challenger will be ignored and the client will receive the following error:
{"error": "invalid command", "code": 2}
Host start match
In order to start the match the host must send the following command:
{"command": "start_match"}
This will start the game thread if the challenger is ready, otherwise the host will receive an error as follow:
{"error": "challenger not ready", "code": 3}
Game phase¶
The game has started and now the pong game screen is built by the clients connected to the same match, taking into account the parameters inside the init message, such as:
{
"message_type": "init",
"ball_radius": 0.02,
"paddle_height": 0.13,
"paddle_width": 0.02
}
During the match the host controls the left paddle and the challenger the right one. In order to play, users can send the following commands:
{"command": "up"}
{"command": "down"}
{"command": "fup"}
{"command": "fdown"}
During the game, for each game_tick
, the websocket server sends the clients all the messages containing the information
necessary to update the game status.
{
"message_type": "status",
"has_bounced": true,
"left_paddle_margin_reached": false,
"right_paddle_margin_reached": true,
"left_score": 4,
"right_score": 3,
"left_paddle_y": 0.5,
"right_paddle_y": 0.3,
"ball_x": 0.6,
"ball_y": 1,
"match_time": 33,
"sudden_death": false
}
When the match is over, the server sends all participants a end message. The information is contained in a serialized completed match object — the same that would be sent from the completed match API.
{
"message_type": "end",
"id": 1,
"winner": "davide",
"loser": "emanuele",
"start_timestamp": "2021-01-16T16:40:51.981401Z",
"completion_timestamp": "2021-01-16T16:41:20.669025Z",
"winner_score": 5,
"loser_score": 4,
"winner_elo_before_match": 1000,
"loser_elo_before_match": 1000,
"winner_elo_after_match": 1050,
"loser_elo_after_match": 950
}