chat/
chat.rs

1use anyhow::Result;
2use iroh::{Endpoint, SecretKey};
3use iroh_gossip::{api::Event, net::Gossip};
4
5// Imports from distrubuted-topic-tracker
6use distributed_topic_tracker::{
7    AutoDiscoveryBuilder, AutoDiscoveryGossip, DefaultSecretRotation, TopicId,
8};
9
10#[tokio::main]
11async fn main() -> Result<()> {
12    // Generate a new random secret key
13    let secret_key = SecretKey::generate(rand::rngs::OsRng);
14
15    // Set up endpoint with discovery enabled
16    let endpoint = Endpoint::builder()
17        .secret_key(secret_key)
18        .discovery_n0()
19        .bind()
20        .await?;
21
22    // Initialize gossip with auto-discovery
23    let gossip = Gossip::builder()
24        .spawn_with_auto_discovery::<DefaultSecretRotation>(endpoint.clone(), None)
25        .await?;
26
27    // Set up protocol router
28    let _router = iroh::protocol::Router::builder(endpoint.clone())
29        .accept(iroh_gossip::ALPN, gossip.gossip.clone())
30        .spawn();
31
32    let topic_id = TopicId::new("my-iroh-gossip-topic".to_string());
33    let initial_secret = b"my-initial-secret".to_vec();
34
35    // Split into sink (sending) and stream (receiving)
36    let (sink, mut stream) = gossip
37        .subscribe_and_join_with_auto_discovery(topic_id, &initial_secret)
38        .await?
39        .split();
40
41    println!("Joined topic");
42
43    // Spawn listener for incoming messages
44    tokio::spawn(async move {
45        while let Ok(event) = stream.recv().await {
46            if let Event::Received(msg) = event {
47                println!(
48                    "\nMessage from {}: {}",
49                    &msg.delivered_from.to_string()[0..8],
50                    String::from_utf8(msg.content.to_vec()).unwrap()
51                );
52            } else if let Event::NeighborUp(peer) = event {
53                println!("\nJoined by {}", &peer.to_string()[0..8]);
54            }
55        }
56    });
57
58    // Main input loop for sending messages
59    let mut buffer = String::new();
60    let stdin = std::io::stdin();
61    loop {
62        print!("\n> ");
63        stdin.read_line(&mut buffer).unwrap();
64        sink.broadcast(buffer.clone().replace("\n", "").into())
65            .await
66            .unwrap();
67        print!(" - (sent)\n");
68        buffer.clear();
69    }
70}