rzv_identify/
rzv-identify.rs1use std::time::Duration;
22
23use futures::StreamExt;
24use libp2p::{
25 identify, noise, ping, rendezvous,
26 swarm::{NetworkBehaviour, SwarmEvent},
27 tcp, yamux, Multiaddr,
28};
29use tracing_subscriber::EnvFilter;
30
31#[tokio::main]
32async fn main() {
33 let _ = tracing_subscriber::fmt()
34 .with_env_filter(EnvFilter::from_default_env())
35 .try_init();
36
37 let rendezvous_point_address = "/ip4/127.0.0.1/tcp/62649".parse::<Multiaddr>().unwrap();
38 let rendezvous_point = "12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN"
39 .parse()
40 .unwrap();
41
42 let mut swarm = libp2p::SwarmBuilder::with_new_identity()
43 .with_tokio()
44 .with_tcp(
45 tcp::Config::default(),
46 noise::Config::new,
47 yamux::Config::default,
48 )
49 .unwrap()
50 .with_behaviour(|key| MyBehaviour {
51 identify: identify::Behaviour::new(identify::Config::new(
52 "rendezvous-example/1.0.0".to_string(),
53 key.public(),
54 )),
55 rendezvous: rendezvous::client::Behaviour::new(key.clone()),
56 ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))),
57 })
58 .unwrap()
59 .build();
60
61 let _ = swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse().unwrap());
62
63 swarm.dial(rendezvous_point_address.clone()).unwrap();
64
65 while let Some(event) = swarm.next().await {
66 match event {
67 SwarmEvent::NewListenAddr { address, .. } => {
68 tracing::info!("Listening on {}", address);
69 }
70 SwarmEvent::ConnectionClosed {
71 peer_id,
72 cause: Some(error),
73 ..
74 } if peer_id == rendezvous_point => {
75 tracing::error!("Lost connection to rendezvous point {}", error);
76 }
77 SwarmEvent::Behaviour(MyBehaviourEvent::Identify(identify::Event::Received {
79 info,
80 ..
81 })) => {
82 swarm.add_external_address(info.observed_addr);
85 if let Err(error) = swarm.behaviour_mut().rendezvous.register(
86 rendezvous::Namespace::from_static("rendezvous"),
87 rendezvous_point,
88 None,
89 ) {
90 tracing::error!("Failed to register: {error}");
91 return;
92 }
93 }
94 SwarmEvent::Behaviour(MyBehaviourEvent::Rendezvous(
95 rendezvous::client::Event::Registered {
96 namespace,
97 ttl,
98 rendezvous_node,
99 },
100 )) => {
101 tracing::info!(
102 "Registered for namespace '{}' at rendezvous point {} for the next {} seconds",
103 namespace,
104 rendezvous_node,
105 ttl
106 );
107 }
108 SwarmEvent::Behaviour(MyBehaviourEvent::Rendezvous(
109 rendezvous::client::Event::RegisterFailed {
110 rendezvous_node,
111 namespace,
112 error,
113 },
114 )) => {
115 tracing::error!(
116 "Failed to register: rendezvous_node={}, namespace={}, error_code={:?}",
117 rendezvous_node,
118 namespace,
119 error
120 );
121 return;
122 }
123 SwarmEvent::Behaviour(MyBehaviourEvent::Ping(ping::Event {
124 peer,
125 result: Ok(rtt),
126 ..
127 })) if peer != rendezvous_point => {
128 tracing::info!("Ping to {} is {}ms", peer, rtt.as_millis())
129 }
130 other => {
131 tracing::debug!("Unhandled {:?}", other);
132 }
133 }
134 }
135}
136
137#[derive(NetworkBehaviour)]
138struct MyBehaviour {
139 identify: identify::Behaviour,
140 rendezvous: rendezvous::client::Behaviour,
141 ping: ping::Behaviour,
142}