Protocol overview
- The Client first tries to log in with his pseudo (LoginPacket)
- The Server then respond with the list of players (PlayerJoinPacket) and tell the client which player he is (ConnexionInfoPacket). All players waits before the server starts the game
- When the game starts, the server sends the resolvable sudoku to everyone (StartGamePacket), the moment the game started and the game duration so that players can properly display the timer. This also allows players to join even if the game already started, so that they display the same synced timer.
- When a player enter a number in the grid, he tells the server (ChangeCellPacket)
- If this action updates his score, the server informs every player (UpdatePlayerScorePacket)
- When a player succeed to complete the grid, the server informs everyone and the game ends (GameEndPacket). All players are now waiting again for the server to start a new game.
Under the hood, every 5s, the server sends a KeepAlivePacket to check for zombified connexions. If the delay is exceeded, the server shuts down the connexion
When a players wants to disconnect (DisconnectPacket) or he's kicked by the server, the server informs all of the remaining players of this event (PlayerLeavePacket).
Packets
Client -> Server
ChangeCellPacket
Packet sent when the client change a number in his grid
| Nom | Type | Description |
|---|---|---|
| SudokuIndex | Int | The index of the sudoku in which the cell was changed |
| CellIndex | Int | The index of the cell in the sudoku |
| NewValue | Int | the new value of the cell |
LoginPacket
The client first sends this packet when the connexion with the server is established
| Nom | Type | Description |
|---|---|---|
| Pseudo | String | The name of the player |
Server -> Client
ConnexionInfoPacket
Used to tell the client which player he is
| Nom | Type | Description |
|---|---|---|
| ConnectionID | Int | The id of the player (client) in the current game |
EndGamePacket
Packet broadcast-ed by the server when the game is over (someone wins or time out)
PlayerJoinPacket
Packet sent when a new player joins the game
| Nom | Type | Description |
|---|---|---|
| Player | Player | The new player |
PlayerLeavePacket
Packet sent when a player leaves the game
| Nom | Type | Description |
|---|---|---|
| PlayerID | Int | The id of the player who left |
StartGamePacket
Packet sent when the admin starts the game (or when a player joins mid game)
| Nom | Type | Description |
|---|---|---|
| Sudoku | String | The serialized sudoku |
| Instant | Instant | The moment when the game started (useful when players join mid game) |
| GameDuration | Long | The duration of the game (in seconds) |
UpdatePlayerScorePacket
Packet send when the score of a player has changed
| Nom | Type | Description |
|---|---|---|
| PlayerID | Int | The id of the player |
| CellsLeft | Int | The numbers of cells left before completing the sudoku |
Server <-> Client
DisconnectPacket
Sent by the server when it shuts down or by the client when it wants to disconnect
| Nom | Type | Description |
|---|---|---|
| Reason | String | The (optional) reason |
KeepAlivePacket
The server send one packet every 5s and the client should respond with the same id or the server shuts down the connexion
| Nom | Type | Description |
|---|---|---|
| KeepAliveID | Long | The id of the keep alive |
Implementation
The connexions are done by Java Sockets, so the protocol used is TCP/IP. A connexion between a client and the server is represented by the abstract Connexion class. This class implements the PacketVisitor interface so that it can process the recieved packets.
The server and the clients inherits this class (ServerConnexion and ClientConnexion) to process the packets based on their needs. A client keeps one ClientConnexion class while the server keeps one ServerConnexion per player. Each Connexion class spawns a new Thread for reading. This means that the server owns a thread per player so it might not scale well with a lot of players. In addition, the server holds another thread to handle new connexions.
When a valid Packet is read by the Connexion class, it calls the visitPacket method on himself to allow different behaviors depending on the packet recieved by subclasses.