Expand description
aeronet
Note: This currently uses Rust nightly. When #91611 is stabilized, this will be switched to stable.
A light-as-air client/server networking library with first-class support for Bevy, providing a consistent API which can be implemented by different transport mechanisms.
Aeronet’s main feature is the transport - an interface for sending data to and receiving data from an endpoint, either the client or the server. You write your code against this interface (or use the Bevy plugin which provides events used by the transport), and you don’t have to worry about the underlying mechanism used to transport your data.
Transports
aeronet_channel
via in-memory MPSC channels, useful for local singleplayer serversaeronet_wt_native
via a Rust implementation of WebTransport, useful for a generic client-server architecture with support for WASM clientsaeronet_wt_wasm
via the browser’s implementation of WebTransport, useful for a WASM app which requires a networking client
Getting started
First, you will need two Message
types to use for sending client-to-server (C2S) and
server-to-client messages (S2C). They may be the same type.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum C2S {
Move(f32),
Shoot,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum S2C {
AddPlayer(String),
UpdateHealth(f32),
}
fn assert_is_message<T: aeronet::Message>() {}
assert_is_message::<C2S>();
assert_is_message::<S2C>();
Create a type implementing TransportProtocol
which uses these message types.
use aeronet::TransportProtocol;
pub enum C2S { /* ... */ }
pub enum S2C { /* ... */ }
#[derive(Debug)]
pub struct AppProtocol;
impl TransportProtocol for AppProtocol {
type C2S = C2S;
type S2C = S2C;
}
Note that certain transport implementations may need you to implement extra traits on your protocol type.
Then, you will need a transport implementation to use. Select one from the list above that suits
your needs. Afterwards, use the TransportClient
and TransportServer
traits to interact with
the transport, to do functions such as sending and receiving data.
use std::time::Duration;
use aeronet::{TransportClient, Rtt};
client.send(C2S::Shoot);
if let Some(conn_info) = client.connection_info() {
let rtt: Duration = conn_info.rtt();
println!("Latency to server: {rtt:?}");
}
Architecture
The traits defined in this crate lay out a client/server architecture - one central server which multiple clients can connect to. The most popular alternative is peer-to-peer, but explaining the differences, advantages, and disadvantages of these architectures are outside the scope of this.
A transport is not necessarily networked - that is, one that communicates to other computers, probably using the internet. Instead, transport can also work using something as simple as in-memory channels or some other non-networked method.
The method used to transport the data itself (i.e. unreliable, reliable ordered, etc.) is also
exposed by this crate - see ChannelKind
for more info.
Protocol
The type of data that is sent between endpoints is a type implementing Message
, but the exact
type is left up to the user of the transport. The user must define their own type implementing
[Protocol
], which specifies what type of message is sent client-to-server and server-to-client,
then use this protocol type throughout their transports.
Transport traits provide no guarantees about in what form the messages are transported. The
memory (and therefore ownership) of the value may be sent directly, in the case of an in-memory
MPSC channel, or may have to be serialized to/from a byte form before being transported. In this
case, TryFromBytes
and TryIntoBytes
are useful to look at.
Connection
This crate abstracts over the complexities of connection by defining two states:
- connected - a client has fully established a connection to a server, including opening the correct streams and channels and all other setup, and messages can now be exchanged between the two
- not connected - any state which isn’t connected
Although the networking implementation is likely to be much more complex, including encryption, handshakes, etc., these two states can be used as a basic contract for networking code. However, the implementation may also choose to expose some more of these details.
Modules
- Utility for pretty-printing errors.
Structs
- Wrapper resource around an async
tokio
runtime. - Forcefully disconnects the client from its currently connected server.
- Forcefully disconnects a client from this server.
- A client sent a message to this server.
- The server sent a message to this client.
- This client has fully connected to a server.
- This client has lost connection from its previously connected server, which cannot be recovered from.
- A client has fully connected to this server.
- A client has lost connection from this server, which cannot be recovered from.
- Sends a message along the server to a client.
- Sends a message along the client to the server.
- Provides systems to send commands to, and receive events from, a
TransportClient
. - Provides systems to send commands to, and receive events from, a
TransportServer
.
Enums
- Represents what kind of method is used to transport data along a connection.
- An event which is raised by a
TransportClient
. - An event which is raised by a
TransportServer
. - Group of systems for sending and receiving data to/from a
TransportClient
. - Group of systems for sending and receiving data to/from a
TransportServer
.
Traits
- Represents a finite set of channels that may be opened by an app.
- Data that can be sent to and received by a transport.
- A type which can be sent along a specific variant of a
ChannelKey
. - Allows access to the remote socket address of the other side of a connection.
- Allows access to the round-trip time of a connection.
- Allows connecting to a server, and transporting messages to/from the server.
- Defines the types of messages sent across a transport channel.
- Allows listening for client connections, and transporting messages to/from the clients connected to this server.
- Data that can potentially be converted from a sequence of bytes into this type.
- Data that can potentially be converted to a sequence of bytes.
Functions
- Provides systems to send commands to, and receive events from, a
TransportClient
. - Provides systems to send commands to, and receive events from, a
TransportServer
.
Derive Macros
- Defines a type of key used to represent the different app-specific channels that can be used to send messages.
- Defines along what variant of a
ChannelKey
a message is sent.