use std::env;
use std::io::{self, Write};
use fastnet::p2p::{P2PSocket, P2PEvent, ConnectionMode};
#[tokio::main]
async fn main() -> io::Result<()> {
let args: Vec<String> = env::args().collect();
let room_id = args.get(1).map(|s| s.as_str()).unwrap_or("default-room");
let signaling_addr = args.get(2).map(|s| s.as_str()).unwrap_or("127.0.0.1:9000");
println!("╔════════════════════════════════════════╗");
println!("║ FastNet P2P Example ║");
println!("╚════════════════════════════════════════╝");
println!();
println!("Connecting to signaling server: {}", signaling_addr);
let mut socket = P2PSocket::connect(signaling_addr).await?;
println!("Connected! Local ID: {}", socket.local_id());
println!("Joining room: {}", room_id);
socket.join_room(room_id).await?;
println!("Joined room successfully!");
println!();
println!("Waiting for other peers...");
println!("(Other peers should run: cargo run --example p2p_peer -- {})", room_id);
println!();
let mut message_count = 0u32;
loop {
for event in socket.poll().await? {
match event {
P2PEvent::PeerJoined(peer_id) => {
println!("📥 Peer {} discovered (attempting connection...)", peer_id);
}
P2PEvent::PeerConnected(peer_id) => {
println!("✅ Direct connection established with peer {}", peer_id);
let greeting = format!("Hello from peer {}!", socket.local_id());
socket.send(peer_id, greeting.into_bytes()).await?;
}
P2PEvent::PeerRelayed(peer_id) => {
println!("🔄 Using relay for peer {} (NAT traversal failed)", peer_id);
let msg = format!("Hello via relay from peer {}!", socket.local_id());
socket.send(peer_id, msg.into_bytes()).await?;
}
P2PEvent::Data(peer_id, data) => {
let message = String::from_utf8_lossy(&data);
let mode = match socket.peer_mode(peer_id) {
Some(ConnectionMode::Direct) => "direct",
Some(ConnectionMode::Relayed) => "relayed",
_ => "unknown",
};
println!("📨 [{}] Peer {}: {}", mode, peer_id, message);
message_count += 1;
let response = format!("Message #{} received!", message_count);
socket.send(peer_id, response.into_bytes()).await?;
}
P2PEvent::PeerLeft(peer_id) => {
println!("👋 Peer {} left", peer_id);
}
P2PEvent::Error(peer_id, error) => {
println!("❌ Error with peer {}: {:?}", peer_id, error);
}
}
}
let peer_count = socket.peer_count();
if peer_count > 0 {
print!("\r📊 Connected peers: {} | Messages: {} ", peer_count, message_count);
io::stdout().flush()?;
}
tokio::time::sleep(tokio::time::Duration::from_millis(16)).await;
}
}