Struct durian::PacketManager

source ·
pub struct PacketManager { /* private fields */ }
Expand description

The core of durian that is the central struct containing all the necessary APIs for initiating and managing connections, creating streams, sending Packets, receiving, broadcasting, etc.

A PacketManager would be created on each client to connect to a single server, and one created on the server to connect to multiple clients. It contains both synchronous and asynchronous APIs, so you can call the functions both from a synchronous context, or within an async runtime (Note: the synchronous path will create a separate isolated async runtime context per PacketManager instance.)

There are 4 basic steps to using the PacketManager, which would be done on both the client and server side:

  1. Create a PacketManager via new() or, if calling from an async context, new_for_async()

  2. Register the Packets and PacketBuilders that the PacketManager will receive and send using register_receive_packet() and register_send_packet().
    The ordering of Packet registration matters for the receive channel and send channel each - the client and server must register the same packets in the same order, for the opposite channels.

    • In other words, the client must register receive packets in the same order the server registers the same as send packets, and vice versa, the client must register send packets in the same order the server registers the same as receive packets. This helps to ensure the client and servers are in sync on what Packets to send/receive, almost like ensuring they are on the same “version” so to speak, and is used to properly identify Packets.
  3. Initiate connection(s) with init_client() (or the async variant async_init_client() if on the client side, else use init_server() (or the async variant async_init_server) if on the server side.

  4. Send packets using any of broadcast(), send(), send_to() or the respective async variants if calling from an async context already. Receive packets using any of received_all() , received(), or the respective async variants.

Example

use durian::{ClientConfig, PacketManager};
use durian_macros::bincode_packet;

#[bincode_packet]
struct Position { x: i32, y: i32 }
#[bincode_packet]
struct ServerAck;
#[bincode_packet]
struct ClientAck;
#[bincode_packet]
struct InputMovement { direction: String }

fn packet_manager_example() {
    // Create PacketManager
    let mut manager = PacketManager::new();

    // Register send and receive packets
    manager.register_receive_packet::<Position>(PositionPacketBuilder).unwrap();
    manager.register_receive_packet::<ServerAck>(ServerAckPacketBuilder).unwrap();
    manager.register_send_packet::<ClientAck>().unwrap();
    manager.register_send_packet::<InputMovement>().unwrap();

    // Initialize a client
    let client_config = ClientConfig::new("127.0.0.1:5001", "127.0.0.1:5000", 2, 2);
    manager.init_client(client_config).unwrap();

    // Send and receive packets
    manager.broadcast(InputMovement { direction: "North".to_string() }).unwrap();
    manager.received_all::<Position, PositionPacketBuilder>(false).unwrap();

    // The above PacketManager is for the client.  Server side is similar except the packets
    // are swapped between receive vs send channels:

    // Create PacketManager
    let mut server_manager = PacketManager::new();

    // Register send and receive packets
    server_manager.register_receive_packet::<ClientAck>(ClientAckPacketBuilder).unwrap();
    server_manager.register_receive_packet::<InputMovement>(InputMovementPacketBuilder).unwrap();
    server_manager.register_send_packet::<Position>().unwrap();
    server_manager.register_send_packet::<ServerAck>().unwrap();

    // Initialize a client
    let client_config = ClientConfig::new("127.0.0.1:5001", "127.0.0.1:5000", 2, 2);
    server_manager.init_client(client_config).unwrap();

    // Send and receive packets
    server_manager.broadcast(Position { x: 1, y: 3 }).unwrap();
    server_manager.received_all::<InputMovement, InputMovementPacketBuilder>(false).unwrap();
}

Implementations§

source§

impl PacketManager

source

pub fn new() -> Self

Create a new PacketManager

If calling from an asynchronous context/runtime, use the new_for_async() variant. This constructs a tokio Runtime for the PacketManager instance.

Panic

If the Runtime could not be created. Usually happens if you call new() from an existing async runtime.

source

pub fn new_for_async() -> Self

Create a new PacketManager

If calling from a synchronous context, use new()

source

pub fn init_client( &mut self, client_config: ClientConfig ) -> Result<(), ConnectionError>

Initialize a client side PacketManager

Arguments
  • client_config - Client configuration
Returns

A Result containing () if successful, else a ConnectionError on error

Panics

When the PacketManager does not have a runtime instance associated with it, which can happen if you created the PacketManager using new_for_async() instead of new().

source

pub async fn async_init_client( &mut self, client_config: ClientConfig ) -> Result<(), ConnectionError>

Initialize a client side PacketManager, to be used if calling from an async context

Arguments
  • client_config - Client configuration
Returns

A Future that returns a Result containing () if successful, else a ConnectionError on error

Panics

When the PacketManager has a runtime instance associated with it, which can happen if you created the PacketManager using new() instead of new_for_async().

source

pub fn init_server( &mut self, server_config: ServerConfig ) -> Result<(), ConnectionError>

Initialize a server side PacketManager

Arguments
  • server_config - Server configuration
Returns

A Result containing () if successful, else a ConnectionError on error

Panics

When the PacketManager does not have a runtime instance associated with it, which can happen if you created the PacketManager using new_for_async() instead of new().

source

pub async fn async_init_server( &mut self, server_config: ServerConfig ) -> Result<(), ConnectionError>

Initialize a server side PacketManager, to be used if calling from an async context

Arguments
  • server_config - Server configuration
Returns

A Future that returns a Result containing () if successful, else a ConnectionError on error

Panics

When the PacketManager has a runtime instance associated with it, which can happen if you created the PacketManager using new() instead of new_for_async().

source

pub fn get_source(&self) -> &(String, Option<Arc<Endpoint>>)

Returns the source address and Endpoint of this PacketManager as a Tuple (String, Option)

Returns

Source address is the server address if this PacketManager is for a server, else the client address. Endpoint is listening Endpoint at the source Socket Address

source

pub fn register_receive_packet<T: Packet + 'static>( &mut self, packet_builder: impl PacketBuilder<T> + 'static + Sync + Send ) -> Result<(), ReceiveError>

Register a Packet on a receive stream/channel, and its associated PacketBuilder

Returns

A Result containing () for success, ReceiveError if registration failed.

source

pub fn register_send_packet<T: Packet + 'static>( &mut self ) -> Result<(), SendError>

Register a Packet on a send stream/channel

Returns

A Result containing () for success, SendError if registration failed.

source

pub fn received_all<T: Packet + 'static, U: PacketBuilder<T> + 'static>( &mut self, blocking: bool ) -> Result<Vec<(u32, Option<Vec<T>>)>, ReceiveError>

Fetches all received packets from all destination addresses

This reads from all receive channels and deserializes the Packets requested. Any channel that is found disconnected will be removed from the stream queue and a warning will be logged. If a reading from a receive channel ran into an unexpected error, this function will stop reading from other channels and return the error.

Type Arguments
  • T: Packet + 'static - The Packet type to request
  • U: PacketBuilder<T> + 'static - The PacketBuilder for this packet, used to deserialize bytes into the Packet type requested
Arguments
  • blocking - true to make this a blocking call, waiting for ALL destination addresses to send at least one Packet of type T. false will make this non-blocking, and any destination addresses that did not send the Packet will return None paired with it. Warning: be careful about making this a blocking call, as if any of the Packets don’t come from any destination address, it could hang your application
Returns

A Result containing a Vec of pair tuples with the first element being the destination socket address, and the second element will have a None if blocking was set to false and the associated destination address did not send the Packet type when this call queried for it, or Some containing a Vec of the Packets type T that was requested from the associated destination address.

ReceiveError if there was an error fetching received packets. If a channel was found disconnected, no Error will be returned with it, but instead it will be removed from the stream queue and output.

Panics

If the PacketManager was created via new_for_async()

source

pub async fn async_received_all<T: Packet + 'static, U: PacketBuilder<T> + 'static>( &mut self, blocking: bool ) -> Result<Vec<(u32, Option<Vec<T>>)>, ReceiveError>

Fetches all received packets from all destination addresses

Same as received_all(), except it returns a Future and can be called from an async context.

Panics

If the PacketManager was created via new()

source

pub fn received<T: Packet + 'static, U: PacketBuilder<T> + 'static>( &mut self, blocking: bool ) -> Result<Option<Vec<T>>, ReceiveError>

Fetches all received packets from a single destination address. This should only be called if there is only one destination address, particularly convenient if this is for a client which connects to a single server.

This reads from the single receive channel and deserializes the Packets requested.

Type Arguments
  • T: Packet + 'static - The Packet type to request
  • U: PacketBuilder<T> + 'static - The PacketBuilder for this packet, used to deserialize bytes into the Packet type requested
Arguments
  • blocking - true to make this a blocking call, waiting for the destination address to send at least one Packet of type T. false will make this non-blocking, and if destination address did not send the Packet, it will return None. Warning: be careful about making this a blocking call, as if Packets don’t arrive exactly as you expect, it could hang your application
Returns

A Result containing None if the destination address did not send any Packets of this type, else Some containing a Vec of those received packets.

ReceiveError if error occurred fetching received packets.

Panics

If the PacketManager was created via new_for_async()

source

pub async fn async_received<T: Packet + 'static, U: PacketBuilder<T> + 'static>( &mut self, blocking: bool ) -> Result<Option<Vec<T>>, ReceiveError>

Fetches all received packets from a single destination address. This should only be called if there is only one destination address, particularly convenient if this is for a client which connects to a single server.

Same as received(), except it returns a Future and can be called from an async context.

Panics

If the PacketManager was created via new()

source

pub fn broadcast<T: Packet + 'static>( &mut self, packet: T ) -> Result<(), SendError>

Broadcast a Packet to all destination addresses

If any send channels are disconnected, they will be removed from the send stream queue and a warning will be logged, and no error will be indicated from this function. If there was an unexpected error, no further packets will be sent, and the function will stop to return an error.

Arguments
  • packet - The Packet to broadcast
Returns

A Result containing () if Packet was sent, else SendError. If a channel was disconnected, it will be removed from the send stream queue and no error will be returned.

Panics

If the PacketManager was created via new_for_async()

source

pub async fn async_broadcast<T: Packet + 'static>( &mut self, packet: T ) -> Result<(), SendError>

Broadcast a Packet to all destination addresses

Same as broadcast(), except it returns a Future and can be called from an async context.

Panics

If the PacketManager was created via new()

source

pub fn send<T: Packet + 'static>(&mut self, packet: T) -> Result<(), SendError>

Send a Packet to the single destination address. This should only be used if there is only one destination address, particularly convenient if this is for a client which connects to a single server.

Arguments
  • packet - The Packet to broadcast
Returns

A Result containing () if Packet was sent, else SendError

Panics

If the PacketManager was created via new_for_async()

source

pub async fn async_send<T: Packet + 'static>( &mut self, packet: T ) -> Result<(), SendError>

Send a Packet to the single destination address. This should only be used if there is only one destination address, particularly convenient if this is for a client which connects to a single server.

Same as send()

Panics

If the PacketManager was created via new()

source

pub fn send_to<T: Packet + 'static>( &mut self, remote_id: u32, packet: T ) -> Result<(), SendError>

Send a Packet to a specified destination address.

Arguments
  • remote_id - The destination Remote Id to send the Packet to
  • packet - The Packet to broadcast
Returns

A Result containing () if Packet was sent, else SendError. In contrast to broadcast(), if the send channel is disconnected, this will return a SendError with error_type == [ErrorType::Disconnect]

Panics

If the PacketManager was created via new_for_async()

source

pub async fn async_send_to<T: Packet + 'static>( &mut self, remote_id: u32, packet: T ) -> Result<(), SendError>

Send a Packet to a specified destination address.

Same as send_to()

Panics
  • If the PacketManager was created via new()
source

pub fn get_num_clients(&self) -> u32

Returns the number of clients attached to this server. This will always return 0 if on a client side.

source

pub async fn async_get_num_clients(&self) -> u32

Returns the number of clients attached to this server. This will always return 0 if on a client side.

source

pub fn get_remote_connections(&self) -> Vec<(u32, String)>

Returns the client connections in tuples of (remote Id, Socket Address)

source

pub async fn async_get_remote_connections(&self) -> Vec<(u32, String)>

Returns the client connections in tuples of (remote Id, Socket Address)

source

pub fn get_remote_address(&self, remote_id: u32) -> Option<String>

Returns the Socket IP Address for a remote Id. Remote Ids start from 0 and are incremented in the order each remote client is connected to the current connection. This can be helpful to associated some sort of numerical ID with clients.

Returns

None if the remote Id was not a valid Id in remote connections. Some containing the Remote address for the requested remote Id.

source

pub async fn async_get_remote_address(&self, remote_id: u32) -> Option<String>

Returns the Socket IP Address for a remote Id. Remote Ids start from 0 and are incremented in the order each remote client is connected to the current connection. This can be helpful to associated some sort of numerical ID with clients.

Same as get_remote_id, except returns a Future and can be called from an async context.

source

pub fn close_connection(&mut self, remote_id: u32) -> Result<(), CloseError>

Close the connection with a destination remote Id

Warning: this will forcefully close the connection, causing any Packets in stream queues that haven’t already sent over the wire to be dropped.

Cleans up resources associated with the connection internal to PacketManager. A Packet will be sent to the destination address detailing the reason of connection closure.

Returns

A Result containing () on success, CloseError if error occurred while closing the connection. Note: connection resources may be partially closed.

source

pub async fn async_close_connection( &mut self, remote_id: u32 ) -> Result<(), CloseError>

Close the connection with a destination Remote Id

Warning: this will forcefully close the connection, causing any Packets in stream queues that haven’t already sent over the wire to be dropped.

Same as close_connection(), except returns a Future and can be called from an async context.

source

pub fn finish_connection(&mut self, remote_id: u32) -> Result<(), CloseError>

Closes the connection with a destination Remote Id after flushing all send streams gracefully.

This differs from close_connection() in that it gracefully flushes all send streams, and waits for acks on each before closing the connection.

Cleans up resources associated with the connection internal to PacketManager. A Packet will be sent to the destination address detailing the reason of connection closure.

Returns

A Result containing () on success, CloseError if error occurred while closing the connection. Note: connection resources may be partially closed.

source

pub async fn async_finish_connection( &mut self, remote_id: u32 ) -> Result<(), CloseError>

Closes the connection with a destination Remote Id after flushing all send streams gracefully.

Same as finish_connection(), except returns a Future and can be called from an async context.

Trait Implementations§

source§

impl Debug for PacketManager

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere 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> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere 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, U> TryFrom<U> for Twhere U: Into<T>,

§

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 Twhere U: TryFrom<T>,

§

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.
§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more