mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-05 06:01:20 +00:00
Merge pull request #62 from tomaka/swarm-docs-pass2
More documentation for libp2p-swarm
This commit is contained in:
commit
c9e6a4d10b
@ -5,19 +5,20 @@ This crate contains all the core traits and mechanisms of the transport system o
|
|||||||
# The `Transport` trait
|
# The `Transport` trait
|
||||||
|
|
||||||
The main trait that this crate provides is `Transport`, which provides the `dial` and
|
The main trait that this crate provides is `Transport`, which provides the `dial` and
|
||||||
`listen_on` methods and can be used to dial or listen on a multiaddress. This crate does not
|
`listen_on` methods and can be used to dial or listen on a multiaddress. The `swarm` crate
|
||||||
provide any concrete (non-dummy, non-adapter) implementation of this trait. It is implemented
|
itself does not provide any concrete (ie. non-dummy, non-adapter) implementation of this trait.
|
||||||
on structs such as `TcpConfig`, `UdpConfig`, `WebsocketConfig` that are provided by external
|
It is implemented on structs that are provided by external crates, such as `TcpConfig` from
|
||||||
crates.
|
`tcp-transport`, `UdpConfig`, or `WebsocketConfig` (note: as of the writing of this
|
||||||
|
documentation, the last two structs don't exist yet).
|
||||||
|
|
||||||
Each implementation of `Transport` only supports *some* multiaddress protocols, for example
|
Each implementation of `Transport` only supports *some* multiaddress protocols, for example
|
||||||
the `TcpConfig` struct only supports multiaddresses that look like `/ip*/*.*.*.*/tcp/*`. Two
|
the `TcpConfig` struct only supports multiaddresses that look like `/ip*/*.*.*.*/tcp/*`. It is
|
||||||
implementations of `Transport` can be grouped together with the `or_transport` method, in order
|
possible to group two implementations of `Transport` with the `or_transport` method, in order
|
||||||
to obtain a single object that supports the protocols of both objects at once. This can be done
|
to obtain a single object that supports the protocols of both objects at once. This can be done
|
||||||
multiple times in order to chain as many implementations as you want.
|
multiple times in a row in order to chain as many implementations as you want.
|
||||||
|
|
||||||
// TODO: right now only tcp-transport exists, but we need to add an example for chaining multiple
|
// TODO: right now only tcp-transport exists, we need to add an example for chaining
|
||||||
// transports once that makes sense
|
// multiple transports once that makes sense
|
||||||
|
|
||||||
# Connection upgrades
|
# Connection upgrades
|
||||||
|
|
||||||
@ -29,22 +30,23 @@ A potential connection upgrade is represented with the `ConnectionUpgrade` trait
|
|||||||
consists in a protocol name plus a method that turns the socket into an `Output` object whose
|
consists in a protocol name plus a method that turns the socket into an `Output` object whose
|
||||||
nature and type is specific to each upgrade.
|
nature and type is specific to each upgrade.
|
||||||
|
|
||||||
There exists two kinds of connection upgrades: middlewares, and actual protocols.
|
There exists three kinds of connection upgrades: middlewares, muxers, and actual protocols.
|
||||||
|
|
||||||
## Middlewares
|
## Middlewares
|
||||||
|
|
||||||
Examples of middleware protocol upgrades include `PlainTextConfig` (dummy upgrade),
|
Examples of middleware connection upgrades include `PlainTextConfig` (dummy upgrade) or
|
||||||
`SecioConfig` (encyption layer), or `MultiplexConfig`.
|
`SecioConfig` (encyption layer, provided by the `secio` crate).
|
||||||
|
|
||||||
The output of a middleware protocol upgrade must implement the `AsyncRead` and `AsyncWrite`
|
The output of a middleware connection upgrade must implement the `AsyncRead` and `AsyncWrite`
|
||||||
traits, just like sockets do.
|
traits, just like sockets do.
|
||||||
|
|
||||||
A middleware can be applied by using the `with_upgrade` method of the `Transport` trait. The
|
A middleware can be applied on a transport by using the `with_upgrade` method of the
|
||||||
return value of this method also implements the `Transport` trait, which means that you can
|
`Transport` trait. The return value of this method also implements the `Transport` trait, which
|
||||||
call `dial()` and `listen_on()` on it in order to directly obtain an upgraded connection. An
|
means that you can call `dial()` and `listen_on()` on it in order to directly obtain an
|
||||||
error is produced if the remote doesn't support the protocol that you are trying to negotiate.
|
upgraded connection or a listener that will yield upgraded connections. An error is produced if
|
||||||
|
the remote doesn't support the protocol corresponding to the connection upgrade.
|
||||||
|
|
||||||
```
|
```rust
|
||||||
extern crate libp2p_swarm;
|
extern crate libp2p_swarm;
|
||||||
extern crate libp2p_tcp_transport;
|
extern crate libp2p_tcp_transport;
|
||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
@ -53,22 +55,37 @@ use libp2p_swarm::Transport;
|
|||||||
|
|
||||||
let tokio_core = tokio_core::reactor::Core::new().unwrap();
|
let tokio_core = tokio_core::reactor::Core::new().unwrap();
|
||||||
let tcp_transport = libp2p_tcp_transport::TcpConfig::new(tokio_core.handle());
|
let tcp_transport = libp2p_tcp_transport::TcpConfig::new(tokio_core.handle());
|
||||||
let upgraded = tcp_transport.with_upgrade(libp2p_swarm::PlainText);
|
let upgraded = tcp_transport.with_upgrade(libp2p_swarm::PlainTextConfig);
|
||||||
|
|
||||||
// upgraded.dial(...) // automatically applies the plain text protocol on the socket
|
// upgraded.dial(...) // automatically applies the plain text protocol on the socket
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Muxers
|
||||||
|
|
||||||
|
The concept of *muxing* consists in using a single stream as if it was multiple substreams.
|
||||||
|
|
||||||
|
If the output of the connection upgrade instead implements the `StreamMuxer` and `Clone`
|
||||||
|
traits, then you can turn the `UpgradedNode` struct into a `ConnectionReuse` struct by calling
|
||||||
|
`ConnectionReuse::from(upgraded_node)`.
|
||||||
|
|
||||||
|
The `ConnectionReuse` struct then implements the `Transport` trait, and can be used to dial or
|
||||||
|
listen to multiaddresses, just like any other transport. The only difference is that dialing
|
||||||
|
a node will try to open a new substream on an existing connection instead of opening a new
|
||||||
|
one every time.
|
||||||
|
|
||||||
|
TODO: add an example once the multiplex pull request is merged
|
||||||
|
|
||||||
## Actual protocols
|
## Actual protocols
|
||||||
|
|
||||||
*Actual protocols* work the same way as middlewares, except that their `Output` doesn't
|
*Actual protocols* work the same way as middlewares, except that their `Output` doesn't
|
||||||
implement the `AsyncRead` and `AsyncWrite` traits. The consequence of this is that the return
|
implement the `AsyncRead` and `AsyncWrite` traits. This means that that the return value of
|
||||||
value of `with_upgrade` **cannot** doesn't implement the `Transport` trait and thus cannot be
|
`with_upgrade` does **not** implement the `Transport` trait and thus cannot be used as a
|
||||||
used as a transport.
|
transport.
|
||||||
|
|
||||||
However the value returned by `with_upgrade` still provides methods named `dial` and
|
However the `UpgradedNode` struct returned by `with_upgrade` still provides methods named
|
||||||
`listen_on`, which will yield you respectively a `Future` or a `Stream`, which you can use to
|
`dial` and `listen_on`, which will yield you respectively a `Future` or a `Stream`, which you
|
||||||
obtain the `Output`. This `Output` can then be used in a protocol-specific way to use the
|
can use to obtain the `Output`. This `Output` can then be used in a protocol-specific way to
|
||||||
protocol.
|
use the protocol.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
@ -102,4 +119,3 @@ core.run(ping_finished_future).unwrap();
|
|||||||
You can use the `.or_upgrade()` method to group multiple upgrades together. The return value
|
You can use the `.or_upgrade()` method to group multiple upgrades together. The return value
|
||||||
also implements the `ConnectionUpgrade` trait and will choose one of the protocols amongst the
|
also implements the `ConnectionUpgrade` trait and will choose one of the protocols amongst the
|
||||||
ones supported.
|
ones supported.
|
||||||
|
|
||||||
|
@ -28,19 +28,20 @@
|
|||||||
//! # The `Transport` trait
|
//! # The `Transport` trait
|
||||||
//!
|
//!
|
||||||
//! The main trait that this crate provides is `Transport`, which provides the `dial` and
|
//! The main trait that this crate provides is `Transport`, which provides the `dial` and
|
||||||
//! `listen_on` methods and can be used to dial or listen on a multiaddress. This crate does not
|
//! `listen_on` methods and can be used to dial or listen on a multiaddress. The `swarm` crate
|
||||||
//! provide any concrete (non-dummy, non-adapter) implementation of this trait. It is implemented
|
//! itself does not provide any concrete (ie. non-dummy, non-adapter) implementation of this trait.
|
||||||
//! on structs such as `TcpConfig`, `UdpConfig`, `WebsocketConfig` that are provided by external
|
//! It is implemented on structs that are provided by external crates, such as `TcpConfig` from
|
||||||
//! crates.
|
//! `tcp-transport`, `UdpConfig`, or `WebsocketConfig` (note: as of the writing of this
|
||||||
|
//! documentation, the last two structs don't exist yet).
|
||||||
//!
|
//!
|
||||||
//! Each implementation of `Transport` only supports *some* multiaddress protocols, for example
|
//! Each implementation of `Transport` only supports *some* multiaddress protocols, for example
|
||||||
//! the `TcpConfig` struct only supports multiaddresses that look like `/ip*/*.*.*.*/tcp/*`. Two
|
//! the `TcpConfig` struct only supports multiaddresses that look like `/ip*/*.*.*.*/tcp/*`. It is
|
||||||
//! implementations of `Transport` can be grouped together with the `or_transport` method, in order
|
//! possible to group two implementations of `Transport` with the `or_transport` method, in order
|
||||||
//! to obtain a single object that supports the protocols of both objects at once. This can be done
|
//! to obtain a single object that supports the protocols of both objects at once. This can be done
|
||||||
//! multiple times in order to chain as many implementations as you want.
|
//! multiple times in a row in order to chain as many implementations as you want.
|
||||||
//!
|
//!
|
||||||
//! // TODO: right now only tcp-transport exists, but we need to add an example for chaining multiple
|
//! // TODO: right now only tcp-transport exists, we need to add an example for chaining
|
||||||
//! // transports once that makes sense
|
//! // multiple transports once that makes sense
|
||||||
//!
|
//!
|
||||||
//! # Connection upgrades
|
//! # Connection upgrades
|
||||||
//!
|
//!
|
||||||
@ -52,20 +53,21 @@
|
|||||||
//! consists in a protocol name plus a method that turns the socket into an `Output` object whose
|
//! consists in a protocol name plus a method that turns the socket into an `Output` object whose
|
||||||
//! nature and type is specific to each upgrade.
|
//! nature and type is specific to each upgrade.
|
||||||
//!
|
//!
|
||||||
//! There exists two kinds of connection upgrades: middlewares, and actual protocols.
|
//! There exists three kinds of connection upgrades: middlewares, muxers, and actual protocols.
|
||||||
//!
|
//!
|
||||||
//! ## Middlewares
|
//! ## Middlewares
|
||||||
//!
|
//!
|
||||||
//! Examples of middleware protocol upgrades include `PlainTextConfig` (dummy upgrade),
|
//! Examples of middleware connection upgrades include `PlainTextConfig` (dummy upgrade) or
|
||||||
//! `SecioConfig` (encyption layer), or `MultiplexConfig`.
|
//! `SecioConfig` (encyption layer, provided by the `secio` crate).
|
||||||
//!
|
//!
|
||||||
//! The output of a middleware protocol upgrade must implement the `AsyncRead` and `AsyncWrite`
|
//! The output of a middleware connection upgrade must implement the `AsyncRead` and `AsyncWrite`
|
||||||
//! traits, just like sockets do.
|
//! traits, just like sockets do.
|
||||||
//!
|
//!
|
||||||
//! A middleware can be applied by using the `with_upgrade` method of the `Transport` trait. The
|
//! A middleware can be applied on a transport by using the `with_upgrade` method of the
|
||||||
//! return value of this method also implements the `Transport` trait, which means that you can
|
//! `Transport` trait. The return value of this method also implements the `Transport` trait, which
|
||||||
//! call `dial()` and `listen_on()` on it in order to directly obtain an upgraded connection. An
|
//! means that you can call `dial()` and `listen_on()` on it in order to directly obtain an
|
||||||
//! error is produced if the remote doesn't support the protocol that you are trying to negotiate.
|
//! upgraded connection or a listener that will yield upgraded connections. An error is produced if
|
||||||
|
//! the remote doesn't support the protocol corresponding to the connection upgrade.
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! extern crate libp2p_swarm;
|
//! extern crate libp2p_swarm;
|
||||||
@ -82,18 +84,33 @@
|
|||||||
//! // upgraded.dial(...) // automatically applies the plain text protocol on the socket
|
//! // upgraded.dial(...) // automatically applies the plain text protocol on the socket
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
//!
|
||||||
|
//! ## Muxers
|
||||||
|
//!
|
||||||
|
//! The concept of *muxing* consists in using a single stream as if it was multiple substreams.
|
||||||
|
//!
|
||||||
|
//! If the output of the connection upgrade instead implements the `StreamMuxer` and `Clone`
|
||||||
|
//! traits, then you can turn the `UpgradedNode` struct into a `ConnectionReuse` struct by calling
|
||||||
|
//! `ConnectionReuse::from(upgraded_node)`.
|
||||||
|
//!
|
||||||
|
//! The `ConnectionReuse` struct then implements the `Transport` trait, and can be used to dial or
|
||||||
|
//! listen to multiaddresses, just like any other transport. The only difference is that dialing
|
||||||
|
//! a node will try to open a new substream on an existing connection instead of opening a new
|
||||||
|
//! one every time.
|
||||||
|
//!
|
||||||
|
//! TODO: add an example once the multiplex pull request is merged
|
||||||
//!
|
//!
|
||||||
//! ## Actual protocols
|
//! ## Actual protocols
|
||||||
//!
|
//!
|
||||||
//! *Actual protocols* work the same way as middlewares, except that their `Output` doesn't
|
//! *Actual protocols* work the same way as middlewares, except that their `Output` doesn't
|
||||||
//! implement the `AsyncRead` and `AsyncWrite` traits. The consequence of this is that the return
|
//! implement the `AsyncRead` and `AsyncWrite` traits. This means that that the return value of
|
||||||
//! value of `with_upgrade` **cannot** doesn't implement the `Transport` trait and thus cannot be
|
//! `with_upgrade` does **not** implement the `Transport` trait and thus cannot be used as a
|
||||||
//! used as a transport.
|
//! transport.
|
||||||
//!
|
//!
|
||||||
//! However the value returned by `with_upgrade` still provides methods named `dial` and
|
//! However the `UpgradedNode` struct returned by `with_upgrade` still provides methods named
|
||||||
//! `listen_on`, which will yield you respectively a `Future` or a `Stream`, which you can use to
|
//! `dial` and `listen_on`, which will yield you respectively a `Future` or a `Stream`, which you
|
||||||
//! obtain the `Output`. This `Output` can then be used in a protocol-specific way to use the
|
//! can use to obtain the `Output`. This `Output` can then be used in a protocol-specific way to
|
||||||
//! protocol.
|
//! use the protocol.
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! extern crate futures;
|
//! extern crate futures;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user