use iroh::{
Endpoint, NodeAddr,
endpoint::Connection,
protocol::{AcceptError, ProtocolHandler, Router},
};
use n0_snafu::{Result, ResultExt};
use n0_watcher::Watcher as _;
const ALPN: &[u8] = b"iroh-example/echo/0";
#[tokio::main]
async fn main() -> Result<()> {
let router = start_accept_side().await?;
let node_addr = router.endpoint().node_addr().initialized().await;
connect_side(node_addr).await?;
router.shutdown().await.e()?;
Ok(())
}
async fn connect_side(addr: NodeAddr) -> Result<()> {
let endpoint = Endpoint::builder().discovery_n0().bind().await?;
let conn = endpoint.connect(addr, ALPN).await?;
let (mut send, mut recv) = conn.open_bi().await.e()?;
send.write_all(b"Hello, world!").await.e()?;
send.finish().e()?;
let response = recv.read_to_end(1000).await.e()?;
assert_eq!(&response, b"Hello, world!");
conn.close(0u32.into(), b"bye!");
endpoint.close().await;
Ok(())
}
async fn start_accept_side() -> Result<Router> {
let endpoint = Endpoint::builder().discovery_n0().bind().await?;
let router = Router::builder(endpoint).accept(ALPN, Echo).spawn();
Ok(router)
}
#[derive(Debug, Clone)]
struct Echo;
impl ProtocolHandler for Echo {
async fn accept(&self, connection: Connection) -> Result<(), AcceptError> {
let node_id = connection.remote_node_id()?;
println!("accepted connection from {node_id}");
let (mut send, mut recv) = connection.accept_bi().await?;
let bytes_sent = tokio::io::copy(&mut recv, &mut send).await?;
println!("Copied over {bytes_sent} byte(s)");
send.finish()?;
connection.closed().await;
Ok(())
}
}