veloren_network/
lib.rs

1#![deny(unsafe_code)]
2#![cfg_attr(test, deny(rust_2018_idioms))]
3#![cfg_attr(test, deny(warnings))]
4#![deny(clippy::clone_on_ref_ptr)]
5#![feature(assert_matches)]
6
7//! Crate to handle high level networking of messages with different
8//! requirements and priorities over a number of protocols
9//!
10//! To start with the `veloren_network` crate you should focus on the 3
11//! elementar structs [`Network`], [`Participant`] and [`Stream`].
12//!
13//! Say you have an application that wants to communicate with other application
14//! over a Network or on the same computer. Now each application instances the
15//! struct [`Network`] once with a new [`Pid`]. The Pid is necessary to identify
16//! other [`Networks`] over the network protocols (e.g. TCP, UDP, QUIC, MPSC)
17//!
18//! To connect to another application, you must know it's [`ConnectAddr`]. One
19//! side will call [`connect`], the other [`connected`]. If successful both
20//! applications will now get a [`Participant`].
21//!
22//! This [`Participant`] represents the connection between those 2 applications.
23//! over the respective [`ConnectAddr`] and with it the chosen network
24//! protocol. However messages can't be send directly via [`Participants`],
25//! instead you must open a [`Stream`] on it. Like above, one side has to call
26//! [`open`], the other [`opened`]. [`Streams`] can have a different priority
27//! and [`Promises`].
28//!
29//! You can now use the [`Stream`] to [`send`] and [`recv`] in both directions.
30//! You can send all kind of messages that implement [`serde`].
31//! As the receiving side needs to know the format, it sometimes is useful to
32//! always send a specific Enum and then handling it with a big `match`
33//! statement This create makes heavily use of `async`, except for [`send`]
34//! which returns always directly.
35//!
36//! For best practices see the `examples` folder of this crate containing useful
37//! code snippets, a simple client/server below. Of course due to the async
38//! nature, no strict client server separation is necessary
39//!
40//! # Examples
41//! ```rust
42//! use std::sync::Arc;
43//! use tokio::{join, runtime::Runtime, time::sleep};
44//! use veloren_network::{ConnectAddr, ListenAddr, Network, Pid, Promises};
45//!
46//! // Client
47//! async fn client(runtime: &Runtime) -> Result<(), Box<dyn std::error::Error>> {
48//!     sleep(std::time::Duration::from_secs(1)).await; // `connect` MUST be after `listen`
49//!     let client_network = Network::new(Pid::new(), runtime);
50//!     let server = client_network
51//!         .connect(ConnectAddr::Tcp("127.0.0.1:12345".parse().unwrap()))
52//!         .await?;
53//!     let mut stream = server
54//!         .open(4, Promises::ORDERED | Promises::CONSISTENCY, 0)
55//!         .await?;
56//!     stream.send("Hello World")?;
57//!     Ok(())
58//! }
59//!
60//! // Server
61//! async fn server(runtime: &Runtime) -> Result<(), Box<dyn std::error::Error>> {
62//!     let mut server_network = Network::new(Pid::new(), runtime);
63//!     server_network
64//!         .listen(ListenAddr::Tcp("127.0.0.1:12345".parse().unwrap()))
65//!         .await?;
66//!     let mut client = server_network.connected().await?;
67//!     let mut stream = client.opened().await?;
68//!     let msg: String = stream.recv().await?;
69//!     println!("Got message: {}", msg);
70//!     assert_eq!(msg, "Hello World");
71//!     Ok(())
72//! }
73//!
74//! fn main() -> Result<(), Box<dyn std::error::Error>> {
75//!     let runtime = Runtime::new().unwrap();
76//!     runtime.block_on(async {
77//!         let (result_c, result_s) = join!(client(&runtime), server(&runtime),);
78//!         result_c?;
79//!         result_s?;
80//!         Ok(())
81//!     })
82//! }
83//! ```
84//!
85//! [`Network`]: crate::api::Network
86//! [`Networks`]: crate::api::Network
87//! [`connect`]: crate::api::Network::connect
88//! [`connected`]: crate::api::Network::connected
89//! [`Participant`]: crate::api::Participant
90//! [`Participants`]: crate::api::Participant
91//! [`open`]: crate::api::Participant::open
92//! [`opened`]: crate::api::Participant::opened
93//! [`Stream`]: crate::api::Stream
94//! [`Streams`]: crate::api::Stream
95//! [`send`]: crate::api::Stream::send
96//! [`recv`]: crate::api::Stream::recv
97//! [`Pid`]: network_protocol::Pid
98//! [`ListenAddr`]: crate::api::ListenAddr
99//! [`ConnectAddr`]: crate::api::ConnectAddr
100//! [`Promises`]: network_protocol::Promises
101
102mod api;
103mod channel;
104mod message;
105mod metrics;
106mod participant;
107mod scheduler;
108mod util;
109
110pub use api::{
111    ConnectAddr, ListenAddr, Network, NetworkConnectError, NetworkError, Participant,
112    ParticipantError, ParticipantEvent, Stream, StreamError, StreamParams,
113};
114pub use message::Message;
115pub use network_protocol::{InitProtocolError, Pid, Promises};