|
| 1 | +use anyhow::Result; |
| 2 | +use libp2p::dns::TokioDnsConfig; |
| 3 | +use libp2p::futures::StreamExt; |
| 4 | +use libp2p::rendezvous::{Config, Rendezvous}; |
| 5 | +use libp2p::swarm::{SwarmBuilder, SwarmEvent}; |
| 6 | +use libp2p::tcp::TokioTcpConfig; |
| 7 | +use libp2p::Transport; |
| 8 | +use libp2p::{identity, rendezvous}; |
| 9 | +use libp2p::{Multiaddr, PeerId}; |
| 10 | +use rendezvous_server::transport::authenticate_and_multiplex; |
| 11 | +use structopt::StructOpt; |
| 12 | + |
| 13 | +#[derive(Debug, StructOpt)] |
| 14 | +struct Cli { |
| 15 | + #[structopt(long = "rendezvous-peer_id")] |
| 16 | + pub rendezvous_peer_id: PeerId, |
| 17 | + #[structopt(long = "rendezvous-addr")] |
| 18 | + pub rendezvous_addr: Multiaddr, |
| 19 | + #[structopt(long = "namespace")] |
| 20 | + pub namespace: String, |
| 21 | +} |
| 22 | + |
| 23 | +#[tokio::main] |
| 24 | +async fn main() -> Result<()> { |
| 25 | + let cli = Cli::from_args(); |
| 26 | + |
| 27 | + let identity = identity::Keypair::generate_ed25519(); |
| 28 | + |
| 29 | + let rendezvous_point_address = cli.rendezvous_addr; |
| 30 | + let rendezvous_point = cli.rendezvous_peer_id; |
| 31 | + |
| 32 | + let tcp_with_dns = TokioDnsConfig::system(TokioTcpConfig::new().nodelay(true)).unwrap(); |
| 33 | + |
| 34 | + let transport = authenticate_and_multiplex(tcp_with_dns.boxed(), &identity).unwrap(); |
| 35 | + |
| 36 | + let rendezvous = Rendezvous::new(identity.clone(), Config::default()); |
| 37 | + |
| 38 | + let peer_id = PeerId::from(identity.public()); |
| 39 | + |
| 40 | + let mut swarm = SwarmBuilder::new(transport, rendezvous, peer_id) |
| 41 | + .executor(Box::new(|f| { |
| 42 | + tokio::spawn(f); |
| 43 | + })) |
| 44 | + .build(); |
| 45 | + |
| 46 | + println!("Local peer id: {}", swarm.local_peer_id()); |
| 47 | + |
| 48 | + swarm.dial_addr(rendezvous_point_address.clone()).unwrap(); |
| 49 | + |
| 50 | + while let Some(event) = swarm.next().await { |
| 51 | + match event { |
| 52 | + SwarmEvent::ConnectionEstablished { peer_id, .. } if peer_id == rendezvous_point => { |
| 53 | + println!( |
| 54 | + "Connected to rendezvous point, discovering nodes in '{}' namespace ...", |
| 55 | + cli.namespace |
| 56 | + ); |
| 57 | + |
| 58 | + swarm.behaviour_mut().discover( |
| 59 | + Some(cli.namespace.to_string()), |
| 60 | + None, |
| 61 | + None, |
| 62 | + rendezvous_point, |
| 63 | + ); |
| 64 | + } |
| 65 | + SwarmEvent::UnreachableAddr { error, address, .. } |
| 66 | + | SwarmEvent::UnknownPeerUnreachableAddr { error, address, .. } |
| 67 | + if address == rendezvous_point_address => |
| 68 | + { |
| 69 | + println!( |
| 70 | + "Failed to connect to rendezvous point at {}: {}", |
| 71 | + address, error |
| 72 | + ); |
| 73 | + } |
| 74 | + SwarmEvent::Behaviour(rendezvous::Event::Discovered { registrations, .. }) => { |
| 75 | + for registration in registrations { |
| 76 | + for address in registration.record.addresses() { |
| 77 | + let peer = registration.record.peer_id(); |
| 78 | + println!("Discovered peer {} at {}", peer, address); |
| 79 | + } |
| 80 | + } |
| 81 | + } |
| 82 | + other => { |
| 83 | + println!("Unhandled {:?}", other); |
| 84 | + } |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | + Ok(()) |
| 89 | +} |
0 commit comments