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    TopicId, AutoDiscoveryGossip, RecordPublisher,
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.clone())
18        .discovery_n0()
19        .bind()
20        .await?;
21
22    // Initialize gossip with auto-discovery
23    let gossip = Gossip::builder()
24        .spawn(endpoint.clone());
25
26    // Set up protocol router
27    let _router = iroh::protocol::Router::builder(endpoint.clone())
28        .accept(iroh_gossip::ALPN, gossip.clone())
29        .spawn();
30
31    let topic_id = TopicId::new("my-iroh-gossip-topic".to_string());
32    let initial_secret = b"my-initial-secret".to_vec();
33
34
35    let record_publisher = RecordPublisher::new(
36        topic_id.clone(),
37        endpoint.node_id().public(),
38        secret_key.secret().clone(),
39        None,
40        initial_secret,
41    );
42        
43    // Split into sink (sending) and stream (receiving)
44    let (gossip_sender, gossip_receiver) = gossip
45        .subscribe_and_join_with_auto_discovery(record_publisher)
46        .await?
47        .split().await?;
48
49    println!("Joined topic");
50
51    // Spawn listener for incoming messages
52    tokio::spawn(async move {
53        while let Some(Ok(event)) = gossip_receiver.next().await {
54            if let Event::Received(msg) = event {
55                println!(
56                    "\nMessage from {}: {}",
57                    &msg.delivered_from.to_string()[0..8],
58                    String::from_utf8(msg.content.to_vec()).unwrap()
59                );
60            } else if let Event::NeighborUp(peer) = event {
61                println!("\nJoined by {}", &peer.to_string()[0..8]);
62            }
63        }
64    });
65
66    // Main input loop for sending messages
67    let mut buffer = String::new();
68    let stdin = std::io::stdin();
69    loop {
70        print!("\n> ");
71        stdin.read_line(&mut buffer).unwrap();
72        gossip_sender.broadcast(buffer.clone().replace("\n", "").into())
73            .await
74            .unwrap();
75        println!(" - (sent)");
76        buffer.clear();
77    }
78}