Skip to main content

chat_no_wait/
chat_no_wait.rs

1use anyhow::Result;
2use iroh::{Endpoint, SecretKey};
3use iroh_gossip::{api::Event, net::Gossip};
4
5use ed25519_dalek::SigningKey;
6
7// Imports from distributed-topic-tracker
8use distributed_topic_tracker::{AutoDiscoveryGossip, Config, RecordPublisher, TopicId};
9use tracing_subscriber::EnvFilter;
10
11#[tokio::main]
12async fn main() -> Result<()> {
13    tracing_subscriber::fmt()
14        .with_thread_ids(true)
15        .with_ansi(true)
16        .with_env_filter(
17            EnvFilter::try_from_default_env()
18                .unwrap_or_else(|_| EnvFilter::new("distributed_topic_tracker=debug")),
19        )
20        .init();
21
22    // Generate a new random secret key
23    let secret_key = SecretKey::generate();
24    let signing_key = SigningKey::from_bytes(&secret_key.to_bytes());
25
26    // Set up endpoint with discovery enabled
27    let endpoint = Endpoint::builder(iroh::endpoint::presets::N0)
28        .secret_key(secret_key.clone())
29        .bind()
30        .await?;
31
32    // Initialize gossip with auto-discovery
33    let gossip = Gossip::builder().spawn(endpoint.clone());
34
35    // Set up protocol router
36    let _router = iroh::protocol::Router::builder(endpoint.clone())
37        .accept(iroh_gossip::ALPN, gossip.clone())
38        .spawn();
39
40    let topic_id = TopicId::new("my-iroh-gossip-topic".to_string());
41    let initial_secret = b"my-initial-secret".to_vec();
42
43    let record_publisher = RecordPublisher::new(
44        topic_id.clone(),
45        signing_key.clone(),
46        None,
47        initial_secret,
48        Config::default(),
49    );
50    let (gossip_sender, mut gossip_receiver) = gossip
51        .subscribe_and_join_with_auto_discovery_no_wait(record_publisher)
52        .await?
53        .split()
54        .await?;
55
56    println!("Joined topic");
57
58    // Spawn listener for incoming messages
59    tokio::spawn(async move {
60        while let Ok(event) = gossip_receiver.next().await {
61            if let Event::Received(msg) = event {
62                println!(
63                    "\nMessage from {}: {}",
64                    &msg.delivered_from.to_string()[0..8],
65                    String::from_utf8(msg.content.to_vec()).unwrap()
66                );
67            } else if let Event::NeighborUp(peer) = event {
68                println!("\nJoined by {}", &peer.to_string()[0..8]);
69            }
70        }
71        println!("\nGossip receiver stream ended");
72    });
73
74    // Main input loop for sending messages
75    let mut buffer = String::new();
76    let stdin = std::io::stdin();
77    loop {
78        print!("\n> ");
79        stdin.read_line(&mut buffer).unwrap();
80        gossip_sender
81            .broadcast(
82                buffer
83                    .trim_end_matches(&['\r', '\n'][..])
84                    .as_bytes()
85                    .to_vec(),
86            )
87            .await
88            .unwrap();
89        println!(" - (sent)");
90        buffer.clear();
91    }
92}