Back to homepage
ServerCodeWalkthrough
History
Server code walkthrough
Phase-Implementation, Phase-Design
Updated Thu, 26 Dec 2019 00:10:00 +0300 by alfadur

Praise 🦀

General Structure

The server code consists of the following top level modules (in order of inclusion):

  • core : contains the types necessary to implement the server logic.
  • protocol : contains definitions of network protocol messages and code for their (de)serialization.
  • handlers : acts on parsed protocol messages to modify the server state and generate responses to network clients.
  • server : contains the code for IO handling.
  • main : starts the server and runs the main event poll.

Important Types

  • core::client::HwClient and core::room::HwRoom structures are where the most of the game-related data is stored. They are often referenced by core::types::{ClientId, RoomId} identifiers
  • core::server::HwServer is a collection HwClient s and HwRoom s with some additional global server data, and is responsible for maintaining related invariants. For this reason it doesn't provide a public way to retrieve a mutable HwClient or HwRoom reference.
  • core::anteroom::HwAnteroom stores clients that did not yet complete the logic procedure. Those clients are represented by core::anteroom::HwAnteroomClient structure, that only contains a relevant subset of full client data.
  • core::server::HwRoomControl can be requested from a HwServer to modify a room that the current client is located in. This interface is not directly provided by HwServer to avoid constant checks to ensure the client is still in the room.

  • protocol::messages::HwProtocolMessage is a parsed representation of a message from a client.
  • protocol::messages::HwServerMessage is a messaged generated by the server to be deserialized into text protocol and sent to a client.
  • protocol::ProtocolDecoder is an entry point to the network protocol parser.

  • handlers::Response is the structure handlers use for queueing server messages to be sent out, clients to be removed due to server logic, and IO tasks to be performed asynchronously.
  • handlers::IoTask type represents a task for the IO thread than can be queued using Response . The task result will eventually be returned as a handlers::IoResult value.

  • server::io::IoThread represents the thread for handling all IO processing apart from writing/reading from clients' network sockets.
  • server::network::NetworkClient is a structure complements a HwClient with data relevant to network connection handling. A NetworkClient is referenced by the same ClientId as the corresponding HwClient .
  • server::network::NetworkLayer is the top level structure that contains an IoThread , a HwAnteroom , a HwServer , and a collection of NetworkClients . It handles all the dispatching between all these components.

Client Flow

  • A new client is first created by the NetworkLayer when a network connection is established. The relevant network state is stored in a NetworkClient structure.
  • If the server is built with TLS support, the client will remain in server::network module until the TLS handshake is completed.
  • Either way, after the connection is successfully established, a new HwAnteroomClient structure is created for the client and stored in the HwAnteroom
  • From there on, when new data received on client's socked, it's parsed by a ProtocolDecoder and the resulting HwProtocolMessage is passed into handlers module for further dispatching
  • While some general messages are processed directly by handlers , the ones only available in a specific context are passed into a specialized submodule: handlers::inanteroom for clients located in HwAnteroom , handlers::inroom for HwServer clients that are in a HwRoom and handlers::inlobby for those that aren't.
  • When processing of a HwProtocolMessage results in a HwAnteroomClient being successfully logged in, it's immediately moved into the HwServer and extended to a full HwClient .
  • If a handler needs complete remove a client, apart from removing it from HwAnteroom of HwServer it will also queue a request to delete the corresponding NetworkClient on it's Response .