Skip to content

Commit afb22e7

Browse files
authored
Merge 11280b5 into 14795ab
2 parents 14795ab + 11280b5 commit afb22e7

File tree

4 files changed

+112
-100
lines changed

4 files changed

+112
-100
lines changed
Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,81 @@
1-
//! A small example showing how to get a list of nodes that were discovered via [`iroh::discovery::LocalSwarmDiscovery`]. LocalSwarmDiscovery uses [`swarm-discovery`](https://crates.io/crates/swarm-discovery) to discover other nodes in the local network ala mDNS.
1+
//! A small example showing how to get a list of nodes that were discovered via [`iroh::discovery::MdnsDiscovery`]. MdnsDiscovery uses [`swarm-discovery`](https://crates.io/crates/swarm-discovery), an opinionated implementation of mDNS to discover other nodes in the local network.
22
//!
33
//! This example creates an iroh endpoint, a few additional iroh endpoints to discover, waits a few seconds, and reports all of the iroh NodeIds (also called `[iroh::key::PublicKey]`s) it has discovered.
44
//!
5-
//! This is an async, non-determinate process, so the number of NodeIDs discovered each time may be different. If you have other iroh endpoints or iroh nodes with [`LocalSwarmDiscovery`] enabled, it may discover those nodes as well.
5+
//! This is an async, non-determinate process, so the number of NodeIDs discovered each time may be different. If you have other iroh endpoints or iroh nodes with [`MdnsDiscovery`] enabled, it may discover those nodes as well.
66
use std::time::Duration;
77

8-
use iroh::{
9-
discovery::local_swarm_discovery::LocalSwarmDiscovery, endpoint::Source, Endpoint, SecretKey,
10-
};
8+
use anyhow::Result;
9+
use iroh::{node_info::UserData, Endpoint, NodeId};
10+
use n0_future::StreamExt;
11+
use tokio::task::JoinSet;
1112

1213
#[tokio::main]
13-
async fn main() -> anyhow::Result<()> {
14+
async fn main() -> Result<()> {
1415
tracing_subscriber::fmt::init();
15-
println!("locally discovered nodes example!\n");
16-
let mut rng = rand::rngs::OsRng;
17-
let key = SecretKey::generate(&mut rng);
18-
let id = key.public();
19-
println!("creating endpoint {id:?}\n");
20-
let ep = Endpoint::builder()
21-
.secret_key(key)
22-
.discovery(Box::new(LocalSwarmDiscovery::new(id)?))
23-
.bind()
24-
.await?;
16+
println!("Discovering Local Nodes Example!");
2517

26-
let node_count = 5;
27-
println!("creating {node_count} additional endpoints to discover locally:");
28-
let mut discoverable_eps = Vec::with_capacity(node_count);
29-
for _ in 0..node_count {
30-
let key = SecretKey::generate(&mut rng);
31-
let id = key.public();
32-
println!("\t{id:?}");
33-
let ep = Endpoint::builder()
34-
.secret_key(key)
35-
.discovery(Box::new(LocalSwarmDiscovery::new(id)?))
36-
.bind()
37-
.await?;
38-
discoverable_eps.push(ep);
39-
}
18+
let ep = Endpoint::builder().discovery_local_network().bind().await?;
19+
let node_id = ep.node_id();
20+
println!("Created endpoint {}", node_id.fmt_short());
4021

41-
let duration = Duration::from_secs(3);
42-
println!("\nwaiting {duration:?} to allow discovery to occur...\n");
43-
tokio::time::sleep(duration).await;
22+
let user_data = UserData::try_from(String::from("local-nodes-example"))?;
4423

45-
// get an iterator of all the remote nodes this endpoint knows about
46-
let remotes = ep.remote_info_iter();
47-
// filter that list down to the nodes that have a `Source::Discovery` with
48-
// the `service` name [`iroh::discovery::local_swarm_discovery::NAME`]
49-
// If you have a long running node and want to only get the nodes that were
50-
// discovered recently, you can also filter on the `Duration` of the source,
51-
// which indicates how long ago we got information from that source.
52-
let locally_discovered: Vec<_> = remotes
53-
.filter(|remote| {
54-
remote.sources().iter().any(|(source, _duration)| {
55-
if let Source::Discovery { name } = source {
56-
name == iroh::discovery::local_swarm_discovery::NAME
57-
} else {
58-
false
24+
let mut discovery_stream = ep.discovery_stream();
25+
26+
let ud = user_data.clone();
27+
let discovery_stream_task = tokio::spawn(async move {
28+
let mut discovered_nodes: Vec<NodeId> = vec![];
29+
while let Some(item) = discovery_stream.next().await {
30+
match item {
31+
Err(e) => {
32+
tracing::error!("{e}");
33+
return;
5934
}
60-
})
61-
})
62-
.map(|remote| remote.node_id)
63-
.collect();
35+
Ok(item) => {
36+
// if there is no user data, or the user data
37+
// does not indicate that the discovered node
38+
// is a part of the example, ignore it
39+
match item.node_info().data.user_data() {
40+
Some(user_data) if &ud == user_data => {}
41+
_ => {
42+
tracing::error!("found node with unexpected user data, ignoring it");
43+
continue;
44+
}
45+
}
6446

65-
println!("found:");
66-
for id in locally_discovered {
67-
println!("\t{id:?}");
47+
// if we've already found this node, ignore it
48+
// otherwise announce that we have found a new node
49+
if discovered_nodes.contains(&item.node_id()) {
50+
continue;
51+
} else {
52+
discovered_nodes.push(item.node_id());
53+
println!("Found node {}!", item.node_id().fmt_short());
54+
}
55+
}
56+
};
57+
}
58+
});
59+
60+
let mut set = JoinSet::new();
61+
let node_count = 5;
62+
for _ in 0..node_count {
63+
let ud = user_data.clone();
64+
set.spawn(async move {
65+
let ep = Endpoint::builder().discovery_local_network().bind().await?;
66+
ep.set_user_data_for_discovery(Some(ud));
67+
tokio::time::sleep(Duration::from_secs(3)).await;
68+
ep.close().await;
69+
anyhow::Ok(())
70+
});
6871
}
72+
73+
set.join_all().await.iter().for_each(|res| {
74+
if let Err(e) = res {
75+
tracing::error!("{e}");
76+
}
77+
});
78+
ep.close().await;
79+
discovery_stream_task.abort();
6980
Ok(())
7081
}

iroh/src/discovery.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
//! - The [`PkarrResolver`] which can perform lookups from designated [pkarr relay servers]
3535
//! using HTTP.
3636
//!
37-
//! - [`LocalSwarmDiscovery`]: local_swarm_discovery::LocalSwarmDiscovery which is an mDNS
38-
//! implementation.
37+
//! - [`MdnsDiscovery`]: mdns::MdnsDiscovery which uses the crate `swarm-discovery`, an
38+
//! opinionated mDNS implementation, to discover nodes on the local network.
3939
//!
4040
//! - The [`DhtDiscovery`] also uses the [`pkarr`] system but can also publish and lookup
4141
//! records to/from the Mainline DHT.
@@ -69,14 +69,14 @@
6969
//! # }
7070
//! ```
7171
//!
72-
//! To also enable [`LocalSwarmDiscovery`] it can be added as another service in the
72+
//! To also enable [`MdnsDiscovery`] it can be added as another service in the
7373
//! [`ConcurrentDiscovery`]:
7474
//!
7575
//! ```no_run
7676
//! # #[cfg(feature = "discovery-local-network")]
7777
//! # {
7878
//! # use iroh::discovery::dns::DnsDiscovery;
79-
//! # use iroh::discovery::local_swarm_discovery::LocalSwarmDiscovery;
79+
//! # use iroh::discovery::mdns::MdnsDiscovery;
8080
//! # use iroh::discovery::pkarr::PkarrPublisher;
8181
//! # use iroh::discovery::ConcurrentDiscovery;
8282
//! # use iroh::SecretKey;
@@ -86,7 +86,7 @@
8686
//! let discovery = ConcurrentDiscovery::from_services(vec![
8787
//! Box::new(PkarrPublisher::n0_dns(secret_key.clone())),
8888
//! Box::new(DnsDiscovery::n0_dns()),
89-
//! Box::new(LocalSwarmDiscovery::new(secret_key.public())?),
89+
//! Box::new(MdnsDiscovery::new(secret_key.public())?),
9090
//! ]);
9191
//! # Ok(())
9292
//! # }
@@ -102,7 +102,7 @@
102102
//! [`PkarrPublisher`]: pkarr::PkarrPublisher
103103
//! [`DhtDiscovery`]: pkarr::dht::DhtDiscovery
104104
//! [pkarr relay servers]: https://pkarr.org/#servers
105-
//! [`LocalSwarmDiscovery`]: local_swarm_discovery::LocalSwarmDiscovery
105+
//! [`MdnsDiscovery`]: mdns::MdnsDiscovery
106106
//! [`StaticProvider`]: static_provider::StaticProvider
107107
108108
use std::sync::Arc;
@@ -126,7 +126,7 @@ use crate::Endpoint;
126126
pub mod dns;
127127

128128
#[cfg(feature = "discovery-local-network")]
129-
pub mod local_swarm_discovery;
129+
pub mod mdns;
130130
pub mod pkarr;
131131
pub mod static_provider;
132132

@@ -264,6 +264,11 @@ impl DiscoveryItem {
264264
pub fn into_node_addr(self) -> NodeAddr {
265265
self.node_info.into_node_addr()
266266
}
267+
268+
/// Returns any user-defined data.
269+
pub fn user_data(&self) -> Option<UserData> {
270+
self.node_info().data.user_data().cloned()
271+
}
267272
}
268273

269274
impl std::ops::Deref for DiscoveryItem {

0 commit comments

Comments
 (0)