1use anyhow::Result;
2use iroh::{Endpoint, SecretKey};
3use iroh_gossip::{api::Event, net::Gossip};
4
5use distributed_topic_tracker::{AutoDiscoveryGossip, RecordPublisher, TopicId};
7
8#[tokio::main]
9async fn main() -> Result<()> {
10
11 use tracing_subscriber::filter::EnvFilter;
13
14 tracing_subscriber::fmt()
15 .with_thread_ids(true)
16 .with_ansi(true)
17 .with_env_filter(
18 EnvFilter::try_from_default_env()
19 .unwrap_or_else(|_| EnvFilter::new("distributed_topic_tracker=debug"))
20 )
21 .init();
22
23 let secret_key = SecretKey::generate(&mut rand::rng());
25
26 let endpoint = Endpoint::builder()
28 .secret_key(secret_key.clone())
29 .discovery_n0()
30 .bind()
31 .await?;
32
33 let gossip = Gossip::builder().spawn(endpoint.clone());
35
36 let _router = iroh::protocol::Router::builder(endpoint.clone())
38 .accept(iroh_gossip::ALPN, gossip.clone())
39 .spawn();
40
41 let topic_id = TopicId::new("my-iroh-gossip-topic".to_string());
42 let initial_secret = b"my-initial-secret".to_vec();
43
44 let record_publisher = RecordPublisher::new(
45 topic_id.clone(),
46 endpoint.node_id().public(),
47 secret_key.secret().clone(),
48 None,
49 initial_secret,
50 );
51
52 let (gossip_sender, gossip_receiver) = gossip
54 .subscribe_and_join_with_auto_discovery(record_publisher)
55 .await?
56 .split()
57 .await?;
58
59 println!("Joined topic");
60
61 tokio::spawn(async move {
63 while let Some(Ok(event)) = gossip_receiver.next().await {
64 if let Event::Received(msg) = event {
65 println!(
66 "\nMessage from {}: {}",
67 &msg.delivered_from.to_string()[0..8],
68 String::from_utf8(msg.content.to_vec()).unwrap()
69 );
70 } else if let Event::NeighborUp(peer) = event {
71 println!("\nJoined by {}", &peer.to_string()[0..8]);
72 }
73 }
74 });
75
76 let mut buffer = String::new();
78 let stdin = std::io::stdin();
79 loop {
80 print!("\n> ");
81 stdin.read_line(&mut buffer).unwrap();
82 gossip_sender
83 .broadcast(buffer.clone().replace("\n", "").into())
84 .await
85 .unwrap();
86 println!(" - (sent)");
87 buffer.clear();
88 }
89}