A peer is a node in a peer-to-peer network. Unlike a client or server in a client/server system, a peer can request information or computation from others and provide services in turn. Peers need not be identical, and no dedicated server has unique privileges. section 11.1 section 11.5
Peers participate in network tasks such as:
- Listening for incoming connections and initiating connections to other nodes. section 11.3 section 11.1.1
- Exchanging messages, as when one node sends a ping and another responds with a pong. section 11.3
- Discovering nearby nodes; libp2p’s mDNS behavior can find peers on a local network without manually specifying their addresses. section 11.4
Two-node ping
Run one node to listen, then start a second with the first node’s multiaddress. The nodes connect and exchange ping and pong messages repeatedly. section 11.3
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::futures::StreamExt;
use libp2p::ping::{Ping, PingConfig};
use libp2p::{identity, Multiaddr, PeerId};
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let new_key = identity::Keypair::generate_ed25519();
let new_peer_id = PeerId::from(new_key.public());
println!("local peer id is: {:?}", new_peer_id);
let transport = libp2p::development_transport(new_key).await?;
let behaviour = Ping::new(PingConfig::new().with_keep_alive(true)); #1
let mut swarm = Swarm::new(transport, behaviour, new_peer_id);
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; #2
if let Some(remote_peer) = std::env::args().nth(1) { #3
let remote_peer_multiaddr: Multiaddr = remote_peer.parse()?; #3
swarm.dial(remote_peer_multiaddr)?; #3
println!("Dialed remote peer: {:?}", remote_peer); #3
}
loop {
match swarm.select_next_some().await { #4
SwarmEvent::NewListenAddr { address, .. } => {
println!("Listening on local address {:?}", address)
}
SwarmEvent::Behaviour(event) => println!
("Event received from peer is {:?}", event), #5
_ => {}
}
}
}
The Rust example creates a peer identity, configures a ping behavior, listens for connections, and optionally dials a remote multiaddress. section 11.3
use libp2p::{
futures::StreamExt,
identity,
mdns::{Mdns, MdnsConfig, MdnsEvent},
swarm::{Swarm, SwarmEvent},
PeerId,
};
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let id_keys = identity::Keypair::generate_ed25519();
let peer_id = PeerId::from(id_keys.public()); #1
println!("Local peer id: {:?}", peer_id);
let transport = libp2p::development_transport(id_keys).await?; #2
let behaviour = Mdns::new(MdnsConfig::default()).await?; #3
let mut swarm = Swarm::new(transport, behaviour, peer_id); #4
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
loop {
match swarm.select_next_some().await {
SwarmEvent::NewListenAddr { address, .. } => {
println!("Listening on local address {:?}", address)
}
SwarmEvent::Behaviour(MdnsEvent::Discovered(peers)) => {
for (peer, addr) in peers {
println!("discovered {} {}", peer, addr);
}
}
SwarmEvent::Behaviour(MdnsEvent::Expired(expired)) => {
for (peer, addr) in expired {
println!("expired {} {}", peer, addr);
}
}
_ => {}
}
}
}
The Rust example configures mDNS so a node can discover peers on its local network. section 11.4
