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:
-
Create a
PacketManager
vianew()
or, if calling from an async context,new_for_async()
-
Register the
Packets
andPacketBuilders
that thePacketManager
will receive and send usingregister_receive_packet()
andregister_send_packet()
.
The ordering ofPacket
registration matters for thereceive
channel andsend
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 assend
packets, and vice versa, the client must registersend
packets in the same order the server registers the same asreceive
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.
- In other words, the client must register
-
Initiate connection(s) with
init_client()
(or the async variantasync_init_client()
if on the client side, else useinit_server()
(or the async variantasync_init_server)
if on the server side. -
Send packets using any of
broadcast()
,send()
,send_to()
or the respectiveasync
variants if calling from an async context already. Receive packets using any ofreceived_all()
,received()
, or the respectiveasync
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
impl PacketManager
sourcepub fn new() -> Self
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.
sourcepub fn new_for_async() -> Self
pub fn new_for_async() -> Self
Create a new PacketManager
If calling from a synchronous context, use new()
sourcepub fn init_client(
&mut self,
client_config: ClientConfig
) -> Result<(), ConnectionError>
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()
.
sourcepub async fn async_init_client(
&mut self,
client_config: ClientConfig
) -> Result<(), ConnectionError>
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()
.
sourcepub fn init_server(
&mut self,
server_config: ServerConfig
) -> Result<(), ConnectionError>
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()
.
sourcepub async fn async_init_server(
&mut self,
server_config: ServerConfig
) -> Result<(), ConnectionError>
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()
.
sourcepub fn get_source(&self) -> &(String, Option<Arc<Endpoint>>)
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
sourcepub fn register_receive_packet<T: Packet + 'static>(
&mut self,
packet_builder: impl PacketBuilder<T> + 'static + Sync + Send
) -> Result<(), ReceiveError>
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.
sourcepub fn received_all<T: Packet + 'static, U: PacketBuilder<T> + 'static>(
&mut self,
blocking: bool
) -> Result<Vec<(u32, Option<Vec<T>>)>, ReceiveError>
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
- ThePacket
type to requestU: PacketBuilder<T> + 'static
- ThePacketBuilder
for this packet, used to deserialize bytes into thePacket
type requested
Arguments
blocking
-true
to make this a blocking call, waiting for ALL destination addresses to send at least one Packet of typeT
.false
will make this non-blocking, and any destination addresses that did not send the Packet will returnNone
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()
sourcepub async fn async_received_all<T: Packet + 'static, U: PacketBuilder<T> + 'static>(
&mut self,
blocking: bool
) -> Result<Vec<(u32, Option<Vec<T>>)>, ReceiveError>
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()
sourcepub fn received<T: Packet + 'static, U: PacketBuilder<T> + 'static>(
&mut self,
blocking: bool
) -> Result<Option<Vec<T>>, ReceiveError>
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
- ThePacket
type to requestU: PacketBuilder<T> + 'static
- ThePacketBuilder
for this packet, used to deserialize bytes into thePacket
type requested
Arguments
blocking
-true
to make this a blocking call, waiting for the destination address to send at least one Packet of typeT
.false
will make this non-blocking, and if destination address did not send the Packet, it will returnNone
. 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()
sourcepub async fn async_received<T: Packet + 'static, U: PacketBuilder<T> + 'static>(
&mut self,
blocking: bool
) -> Result<Option<Vec<T>>, ReceiveError>
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()
sourcepub fn broadcast<T: Packet + 'static>(
&mut self,
packet: T
) -> Result<(), SendError>
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
- ThePacket
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()
sourcepub async fn async_broadcast<T: Packet + 'static>(
&mut self,
packet: T
) -> Result<(), SendError>
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()
sourcepub fn send<T: Packet + 'static>(&mut self, packet: T) -> Result<(), SendError>
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
- ThePacket
to broadcast
Returns
A Result
containing ()
if Packet was sent, else SendError
Panics
If the PacketManager
was created via new_for_async()
sourcepub fn send_to<T: Packet + 'static>(
&mut self,
remote_id: u32,
packet: T
) -> Result<(), SendError>
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 topacket
- ThePacket
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()
sourcepub async fn async_send_to<T: Packet + 'static>(
&mut self,
remote_id: u32,
packet: T
) -> Result<(), SendError>
pub async fn async_send_to<T: Packet + 'static>( &mut self, remote_id: u32, packet: T ) -> Result<(), SendError>
sourcepub fn get_num_clients(&self) -> u32
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.
sourcepub async fn async_get_num_clients(&self) -> u32
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.
sourcepub fn get_remote_connections(&self) -> Vec<(u32, String)>
pub fn get_remote_connections(&self) -> Vec<(u32, String)>
Returns the client connections in tuples of (remote Id, Socket Address)
sourcepub async fn async_get_remote_connections(&self) -> Vec<(u32, String)>
pub async fn async_get_remote_connections(&self) -> Vec<(u32, String)>
Returns the client connections in tuples of (remote Id, Socket Address)
sourcepub fn get_remote_address(&self, remote_id: u32) -> Option<String>
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.
sourcepub async fn async_get_remote_address(&self, remote_id: u32) -> Option<String>
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.
sourcepub fn close_connection(&mut self, remote_id: u32) -> Result<(), CloseError>
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.
sourcepub async fn async_close_connection(
&mut self,
remote_id: u32
) -> Result<(), CloseError>
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.
sourcepub fn finish_connection(&mut self, remote_id: u32) -> Result<(), CloseError>
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.
sourcepub async fn async_finish_connection(
&mut self,
remote_id: u32
) -> Result<(), CloseError>
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.