CUGL 2.1
Cornell University Game Library
Classes | Public Types | Public Member Functions | Static Public Member Functions | List of all members
cugl::NetworkConnection Class Reference

#include <CUNetworkConnection.h>

Classes

struct  ConnectionConfig
 

Public Types

enum  NetStatus {
  NetStatus::Disconnected, NetStatus::Pending, NetStatus::Connected, NetStatus::Reconnecting,
  NetStatus::RoomNotFound, NetStatus::ApiMismatch, NetStatus::GenericError
}
 

Public Member Functions

 NetworkConnection ()
 
 ~NetworkConnection ()
 
void dispose ()
 
bool init (ConnectionConfig config)
 
bool init (ConnectionConfig config, const std::string roomID)
 
void send (const std::vector< uint8_t > &msg)
 
void sendOnlyToHost (const std::vector< uint8_t > &msg)
 
void receive (const std::function< void(const std::vector< uint8_t > &)> &dispatcher)
 
void startGame ()
 
NetStatus getStatus ()
 
std::optional< uint8_t > getPlayerID () const
 
std::string getRoomID () const
 
bool isPlayerActive (uint8_t playerID)
 
uint8_t getNumPlayers () const
 
uint8_t getTotalPlayers () const
 
bool getDebug () const
 
void setDebug (bool value)
 

Static Public Member Functions

static std::shared_ptr< NetworkConnectionalloc (ConnectionConfig config)
 
static std::shared_ptr< NetworkConnectionalloc (ConnectionConfig config, const std::string roomID)
 

Detailed Description

A class to support a connection to other players with a peer-to-peer interface.

The premise of this class is to make networking as simple as possible. Simply call send with a byte vector, and then all others will receive it when they call receive. You can use NetworkSerializer and NetworkDeserializer to handle more complex types.

This class maintains a networked game using an ad-hoc server setup, but provides an interface that acts like it is peer-to-peer. The "host" is the server, and is the one all others are connected to. The "clients" are other players connected to the ad-hoc server. However, any messages sent are relayed by the host to all other players too, so the interface appears peer-to-peer.

You can use this as a true client-server by just checking the player ID. Player ID 0 is the host, and all others are clients connected to the host.

Using this class requires an external lobby server for NAT punchthrough. This server only handles initial connections. It does not handle actual game data. This reduces server costs significantly. To get an external lobby server for your game, go to

https://hub.docker.com/r/mtxing/cugl-nat-punchthrough

This class does support automatic reconnections, but does NOT support host migration. If the host drops offline, the connection is closed.

Member Enumeration Documentation

◆ NetStatus

Potential states the network connection could be in.

Enumerator
Disconnected 

No connection

Pending 

Waiting on a connection.

If host, this means waiting on Room ID from server. If a client, this means waiting on Player ID from host

Connected 

Fully connected

If host this means accepting connections. If a client, this means successfully connected to host.

Reconnecting 

Lost a connection and attempting to reconnect

Failure causes a disconnection.

RoomNotFound 

The room ID does not exist, or room is already full

ApiMismatch 

API version numbers do not match..

The match must be between host, client, AND the punchthrough server. When running your own punchthrough server, you can specify a minimum API version that your server will require, or else it will reject the connection.

If you are using the demo server for the game lab, the minimum is 0.

GenericError 

Something unknown went wrong

Constructor & Destructor Documentation

◆ NetworkConnection()

cugl::NetworkConnection::NetworkConnection ( )

Creates a degenerate network connection.

The network connection has not yet initialized Slikenet and cannot be used.

NEVER USE A CONSTRUCTOR WITH NEW. If you want to allocate an object on the heap, use one of the static constructors instead.

◆ ~NetworkConnection()

cugl::NetworkConnection::~NetworkConnection ( )

Deletes this network connection, disposing all resources

Member Function Documentation

◆ alloc() [1/2]

static std::shared_ptr<NetworkConnection> cugl::NetworkConnection::alloc ( ConnectionConfig  config)
inlinestatic

Returns a newly allocated network connection as host.

This will automatically connect to the NAT punchthrough server and request a room ID. This process is NOT instantaneous and the initializer will return true even without a guaranteed connection. Wait for getStatus to return CONNECTED. Once it does, getRoomID will return your assigned room ID.

This method will return true if the Slikenet subsystem fails to initialize.

Parameters
configConnection config
Returns
a newly allocated network connection as host.

◆ alloc() [2/2]

static std::shared_ptr<NetworkConnection> cugl::NetworkConnection::alloc ( ConnectionConfig  config,
const std::string  roomID 
)
inlinestatic

Returns a newly allocated network connection as a client.

This will automatically connect to the NAT punchthrough server and then try to connect to the host with the given ID. This process is NOT instantaneous and the initializer will return true even without a guaranteed connection. Wait for getStatus to return CONNECTED. Once it does, getPlayerID will return your assigned player ID.

Parameters
configConnection config
roomIDHost's assigned Room ID
Returns
a newly allocated network connection as a client.

◆ dispose()

void cugl::NetworkConnection::dispose ( )

Disposes all of the resources used by this network connection.

A disposed network connection can be safely reinitialized.

◆ getDebug()

bool cugl::NetworkConnection::getDebug ( ) const
inline

Returns the debug status of this network connection

If the debug status is true, this connection will log verbose messages during the initial handshake and any reconnection attempts. This value should be set to false in a production system.

Returns
the debug status of this network connection

◆ getNumPlayers()

uint8_t cugl::NetworkConnection::getNumPlayers ( ) const
inline

Returns the number of players currently connected to this game

This does not include any players that have been disconnected.

Returns
the number of players currently connected to this game

◆ getPlayerID()

std::optional<uint8_t> cugl::NetworkConnection::getPlayerID ( ) const
inline

Returns the player ID or empty.

If this player is the host, this is guaranteed to be 0, even before a connection is established. Otherwise, as client, this will return empty until connected to host and a player ID is assigned.

Returns
the player ID or empty.

◆ getRoomID()

std::string cugl::NetworkConnection::getRoomID ( ) const
inline

Returns the room ID or empty string.

If this player is a client, this will return the room ID this object was constructed with. Otherwise, as host, this will return the empty string until connected to the punchthrough server and a room ID once it is assigned.

Returns
the room ID or empty string.

◆ getStatus()

NetStatus cugl::NetworkConnection::getStatus ( )

Returns the current status of this network connection.

Returns
the current status of this network connection.

◆ getTotalPlayers()

uint8_t cugl::NetworkConnection::getTotalPlayers ( ) const
inline

Returns the number of players present when the game was started

This includes any players that may have disconnected.

Returns
the number of players present when the game was started

◆ init() [1/2]

bool cugl::NetworkConnection::init ( ConnectionConfig  config)

Initializes a new network connection as host.

This will automatically connect to the NAT punchthrough server and request a room ID. This process is NOT instantaneous and the initializer will return true even without a guaranteed connection. Wait for getStatus to return CONNECTED. Once it does, getRoomID will return your assigned room ID.

This method will return true if the Slikenet subsystem fails to initialize.

Parameters
configConnection config
Returns
true if initialization was successful

◆ init() [2/2]

bool cugl::NetworkConnection::init ( ConnectionConfig  config,
const std::string  roomID 
)

Initializes a new network connection as a client.

This will automatically connect to the NAT punchthrough server and then try to connect to the host with the given ID. This process is NOT instantaneous and the initializer will return true even without a guaranteed connection. Wait for getStatus to return CONNECTED. Once it does, getPlayerID will return your assigned player ID.

Parameters
configConnection config
roomIDHost's assigned Room ID
Returns
true if initialization was successful

◆ isPlayerActive()

bool cugl::NetworkConnection::isPlayerActive ( uint8_t  playerID)
inline

Returns true if the given player ID is currently connected to the game.

This does not return meaningful data until a connection is established. This method is primarily designed for the host. However, a client can test its connection status by using player ID 0.

Parameters
playerIDThe player to test for connection
Returns
true if the given player ID is currently connected to the game.

◆ receive()

void cugl::NetworkConnection::receive ( const std::function< void(const std::vector< uint8_t > &  ) &

Receives incoming network messages.

This method must be called periodically EVEN BEFORE A CONNECTION IS ESTABLISHED. Otherwise, the library has no way to receive and process incoming connections.

When executed, the function dispatch willl be called on every received byte array since the last call to receive. It is up to you to interpret this data on your own or with NetworkDeserializer

A network frame can, but need not be, the same as a render frame. However, during the network connection phase, before the game starts, this method should be called every frame. Otherwise, the NAT Punchthrough library may fail. Afterwards, you can delay this to every few frames if necessary to relieve congestion.

Parameters
dispatcherThe function to process received data

◆ send()

void cugl::NetworkConnection::send ( const std::vector< uint8_t > &  msg)

Sends a byte array to all other players.

Within a few frames, other players should receive this via a call to receive.

This requires a connection be established. Otherwise its behavior is undefined.

You may choose to either send a byte array directly, or you can use the NetworkSerializer and NetworkDeserializer classes to encode more complex data.

Parameters
msgThe byte array to send.

◆ sendOnlyToHost()

void cugl::NetworkConnection::sendOnlyToHost ( const std::vector< uint8_t > &  msg)

Sends a byte array to the host only.

This is only useful when called from a client (player ID != 0). As host, this is method does nothing. Within a few frames, the host should receive this via a call to receive

This requires a connection be established. Otherwise its behavior is undefined.

You may choose to either send a byte array directly, or you can use the NetworkSerializer and NetworkDeserializer classes to encode more complex data.

Parameters
msgThe byte array to send.

◆ setDebug()

void cugl::NetworkConnection::setDebug ( bool  value)
inline

Sets the debug status of this network connection

If the debug status is true, this connection will log verbose messages during the initial handshake and any reconnection attempts. This value should be set to false in a production system.

Parameters
valueThe debug status of this network connection

◆ startGame()

void cugl::NetworkConnection::startGame ( )

Marks the game as started and ban incoming connections except for reconnects.

Note: This can only be called by the host. This method is ignored for players.


The documentation for this class was generated from the following file: