use iroh::{Endpoint, endpoint::presets}; use iroh_gossip::net::Gossip; use peerspeak::network::{PeerState, RoomState, gossip::IrohGossipState}; use tokio::time::{self, Duration}; #[tokio::main] async fn main() -> Result<(), Box> { println!("Starting network loopback test..."); // 1. Node A (Host) Setup let lookup_a = iroh::address_lookup::memory::MemoryLookup::new(); let secret_a = iroh::SecretKey::generate(); let endpoint_a = Endpoint::builder(presets::N0) .secret_key(secret_a.clone()) .address_lookup(lookup_a.clone()) .bind() .await?; endpoint_a.online().await; println!("Node A online. ID: {}", endpoint_a.id()); let gossip_a = Gossip::builder().spawn(endpoint_a.clone()); let _router_a = iroh::protocol::Router::builder(endpoint_a.clone()) .accept(iroh_gossip::net::GOSSIP_ALPN, gossip_a.clone()) .spawn(); let room_a = IrohGossipState::new( endpoint_a.clone(), gossip_a.clone(), lookup_a.clone(), secret_a, ); // 2. Node B (Client) Setup let lookup_b = iroh::address_lookup::memory::MemoryLookup::new(); let secret_b = iroh::SecretKey::generate(); let endpoint_b = Endpoint::builder(presets::N0) .secret_key(secret_b.clone()) .address_lookup(lookup_b.clone()) .bind() .await?; endpoint_b.online().await; println!("Node B online. ID: {}", endpoint_b.id()); let gossip_b = Gossip::builder().spawn(endpoint_b.clone()); let _router_b = iroh::protocol::Router::builder(endpoint_b.clone()) .accept(iroh_gossip::net::GOSSIP_ALPN, gossip_b.clone()) .spawn(); let room_b = IrohGossipState::new( endpoint_b.clone(), gossip_b.clone(), lookup_b.clone(), secret_b, ); // 3. Create room on Node A let topic_id = rand::random(); let ticket = peerspeak::network::PeerSpeakTicket { host_addr: endpoint_a.addr(), topic_id, name: String::new(), }; let ticket_str = ticket.to_string(); println!("Ticket generated: {}", ticket_str); let state_a = PeerState { name: "Alice".to_string(), is_muted: false, addr: endpoint_a.addr(), sharing: None, avatar: Default::default(), game: None, music: None, }; room_a.join(&ticket_str, state_a, vec![]).await?; println!("Node A joined topic."); // Subscribe to events on Node A let mut rx_a = room_a.subscribe_events().await?; tokio::spawn(async move { while let Some(event) = rx_a.recv().await { println!("Node A Event: {:?}", event); } }); // 4. Join room on Node B let state_b = PeerState { name: "Bob".to_string(), is_muted: false, addr: endpoint_b.addr(), sharing: None, avatar: Default::default(), game: None, music: None, }; room_b.join(&ticket_str, state_b, vec![]).await?; println!("Node B joined topic."); // Subscribe to events on Node B let mut rx_b = room_b.subscribe_events().await?; tokio::spawn(async move { while let Some(event) = rx_b.recv().await { println!("Node B Event: {:?}", event); } }); // Wait and check connection println!("Waiting 10 seconds for Gossip sync..."); time::sleep(Duration::from_secs(10)).await; println!("Alice's peers: {:?}", room_a.active_peers()); println!("Bob's peers: {:?}", room_b.active_peers()); println!("Test finished."); Ok(()) }