Expand description
Crate to handle high level networking of messages with different requirements and priorities over a number of protocols
To start with the veloren_network crate you should focus on the 3
elementar structs Network, Participant and Stream.
Say you have an application that wants to communicate with other application
over a Network or on the same computer. Now each application instances the
struct Network once with a new Pid. The Pid is necessary to identify
other Networks over the network protocols (e.g. TCP, UDP, QUIC, MPSC)
To connect to another application, you must know itβs ConnectAddr. One
side will call connect, the other connected. If successful both
applications will now get a Participant.
This Participant represents the connection between those 2 applications.
over the respective ConnectAddr and with it the chosen network
protocol. However messages canβt be send directly via Participants,
instead you must open a Stream on it. Like above, one side has to call
open, the other opened. Streams can have a different priority
and Promises.
You can now use the Stream to send and recv in both directions.
You can send all kind of messages that implement serde.
As the receiving side needs to know the format, it sometimes is useful to
always send a specific Enum and then handling it with a big match
statement This create makes heavily use of async, except for send
which returns always directly.
For best practices see the examples folder of this crate containing useful
code snippets, a simple client/server below. Of course due to the async
nature, no strict client server separation is necessary
Β§Examples
use std::sync::Arc;
use tokio::{join, runtime::Runtime, time::sleep};
use veloren_network::{ConnectAddr, ListenAddr, Network, Pid, Promises};
// Client
async fn client(runtime: &Runtime) -> Result<(), Box<dyn std::error::Error>> {
sleep(std::time::Duration::from_secs(1)).await; // `connect` MUST be after `listen`
let client_network = Network::new(Pid::new(), runtime);
let server = client_network
.connect(ConnectAddr::Tcp("127.0.0.1:12345".parse().unwrap()))
.await?;
let mut stream = server
.open(4, Promises::ORDERED | Promises::CONSISTENCY, 0)
.await?;
stream.send("Hello World")?;
Ok(())
}
// Server
async fn server(runtime: &Runtime) -> Result<(), Box<dyn std::error::Error>> {
let mut server_network = Network::new(Pid::new(), runtime);
server_network
.listen(ListenAddr::Tcp("127.0.0.1:12345".parse().unwrap()))
.await?;
let mut client = server_network.connected().await?;
let mut stream = client.opened().await?;
let msg: String = stream.recv().await?;
println!("Got message: {}", msg);
assert_eq!(msg, "Hello World");
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let runtime = Runtime::new().unwrap();
runtime.block_on(async {
let (result_c, result_s) = join!(client(&runtime), server(&runtime),);
result_c?;
result_s?;
Ok(())
})
}ModulesΒ§
StructsΒ§
- Message
- Support struct used for optimising sending the same Message to multiple
Stream - Network
- Use the
Networkto create connections to otherParticipants - Participant
Participantsare generated by theNetworkand represent a connection to a remote Participant. Look at theconnectandconnectedmethod ofNetworkson how to generateParticipants- Pid
- Support struct used for uniquely identifying
Participantover theNetwork. - Promises
- use promises to modify the behavior of
Streams. see the consts in thisstructfor - Stream
Streamsrepresents a channel to sendnmessages with a certain priority andPromises. messages need always to be send between 2Streams.- Stream
Params - All Parameters of a Stream, can be used to generate RawMessages
EnumsΒ§
- Connect
Addr - Represents a Tcp, Quic, Udp or Mpsc connection address
- Init
Protocol Error - All possible Errors that can happen during Handshake
InitProtocol - Listen
Addr - Represents a Tcp, Quic, Udp or Mpsc listen address
- Network
Connect Error - Error type thrown by
Networksconnect - Network
Error - Error type thrown by
Networksmethods - Participant
Error - Error type thrown by
Participantsmethods - Participant
Event - A Participant can throw different events, you are obligated to carefully empty the queue from time to time.
- Stream
Error - Error type thrown by
Streamsmethods A Compression Error should only happen if a client sends malicious code. A Deserialize Error probably means you are expecting Type X while you actually got send type Y.