Struct Client

Source
pub struct Client<T: Transceiver, Ctx = ()> { /* private fields */ }
Expand description

The netcode client.

To create a client one should obtain a connection token from a web backend (by REST API or other means).
The client will use this token to connect to the dedicated netcode server.

While the client is connected, it can send and receive packets to and from the server.
Similarly to the server, the client should be updated at a fixed rate (e.g., 60Hz) to process incoming packets and send outgoing packets.

§Example

let mut client = Client::new(&token_bytes).unwrap();
client.connect();

let start = Instant::now();
let tick_rate = Duration::from_secs_f64(1.0 / 60.0);
loop {
    client.update(start.elapsed().as_secs_f64());
    if client.is_connected() {
        client.send(b"Hello World!").unwrap();
    }
    if let Some(packet) = client.recv() {
        println!("received packet: {:?}", packet);
    }
    thread::sleep(tick_rate);
}

Implementations§

Source§

impl Client<NetcodeSocket>

Source

pub fn new(token_bytes: &[u8]) -> Result<Self>

Create a new client with a default configuration.

§Example
// Generate a connection token for the client
let private_key = netcode::generate_key();
let token_bytes = ConnectToken::build("127.0.0.1:0", 0, 0, private_key)
    .generate()
    .unwrap()
    .try_into_bytes()
    .unwrap();

let mut client = Client::new(&token_bytes).unwrap();
Source§

impl<Ctx> Client<NetcodeSocket, Ctx>

Source

pub fn with_config(token_bytes: &[u8], cfg: ClientConfig<Ctx>) -> Result<Self>

Create a new client with a custom configuration.
Callbacks with context can be registered with the client to be notified when the client changes states.
See ClientConfig for more details.

§Example
struct MyContext {};
let cfg = ClientConfig::with_context(MyContext {}).on_state_change(|from, to, _ctx| {
   assert_eq!(from, ClientState::Disconnected);
   assert_eq!(to, ClientState::SendingConnectionRequest);
});

let mut client = Client::with_config(&token_bytes, cfg).unwrap();
Source§

impl<T: Transceiver, Ctx> Client<T, Ctx>

Source

pub fn with_config_and_transceiver( token_bytes: &[u8], cfg: ClientConfig<Ctx>, trx: T, ) -> Result<Self>

Creates a new client instance with the given configuration and transceiver.

This is useful if you want to use a custom transceiver implementation, in any other case you should use Client::new or Client::with_config.

§Examples
use netcode::{Client, ClientConfig, ConnectToken, Transceiver};

struct MyTransceiver {
   // ...
};

impl Transceiver for MyTransceiver {
   // ...
}

let cfg = ClientConfig::default();
let trx = MyTransceiver { /* .. */ };

let client = Client::with_config_and_transceiver(&token_bytes, cfg, trx).unwrap();
Source

pub fn connect(&mut self)

Prepares the client to connect to the server.

This function does not perform any IO, it only readies the client to send/receive packets on the next call to update.

Source

pub fn update(&mut self, time: f64)

Updates the client.

  • Updates the client’s elapsed time.
  • Receives packets from the server, any received payload packets will be queued.
  • Sends keep-alive or request/response packets to the server to establish/maintain a connection.
  • Updates the client’s state - checks for timeouts, errors and transitions to new states.

This method should be called regularly, probably at a fixed rate (e.g., 60Hz).

§Panics

Panics if the client can’t send or receive packets. For a non-panicking version, use try_update.

Source

pub fn try_update(&mut self, time: f64) -> Result<()>

The fallible version of update.

Returns an error if the client can’t send or receive packets.

Source

pub fn recv(&mut self) -> Option<Vec<u8>>

Receives a packet from the server, if one is available in the queue.

The packet will be returned as a Vec<u8>.

If no packet is available, None will be returned.

§Example
let mut client = Client::new(&token_bytes).unwrap();
client.connect();

let start = Instant::now();
let tick_rate = Duration::from_secs_f64(1.0 / 60.0);
loop {
    client.update(start.elapsed().as_secs_f64());
    if let Some(packet) = client.recv() {
        // ...
    }
    thread::sleep(tick_rate);
}
Source

pub fn send(&mut self, buf: &[u8]) -> Result<()>

Sends a packet to the server.

The provided buffer must be smaller than MAX_PACKET_SIZE.

Source

pub fn disconnect(&mut self) -> Result<()>

Disconnects the client from the server.

The client will send a number of redundant disconnect packets to the server before transitioning to Disconnected.

Source

pub fn addr(&self) -> SocketAddr

Gets the local SocketAddr that the client is bound to.

Source

pub fn state(&self) -> ClientState

Gets the current state of the client.

Source

pub fn is_error(&self) -> bool

Returns true if the client is in an error state.

Source

pub fn is_pending(&self) -> bool

Returns true if the client is in a pending state.

Source

pub fn is_connected(&self) -> bool

Returns true if the client is connected to a server.

Source

pub fn is_disconnected(&self) -> bool

Returns true if the client is disconnected from the server.

Auto Trait Implementations§

§

impl<T, Ctx> Freeze for Client<T, Ctx>
where T: Freeze, Ctx: Freeze,

§

impl<T, Ctx = ()> !RefUnwindSafe for Client<T, Ctx>

§

impl<T, Ctx> Send for Client<T, Ctx>
where T: Send, Ctx: Send,

§

impl<T, Ctx> Sync for Client<T, Ctx>
where T: Sync, Ctx: Sync,

§

impl<T, Ctx> Unpin for Client<T, Ctx>
where T: Unpin, Ctx: Unpin,

§

impl<T, Ctx = ()> !UnwindSafe for Client<T, Ctx>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.