use anyhow::Result;
use iroh::{
endpoint::Connection,
protocol::{ProtocolHandler, Router},
Endpoint, NodeAddr,
};
use n0_future::boxed::BoxFuture;
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().await?;
connect_side(node_addr).await?;
router.shutdown().await?;
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?;
send.write_all(b"Hello, world!").await?;
send.finish()?;
let response = recv.read_to_end(1000).await?;
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 {
fn accept(&self, connection: Connection) -> BoxFuture<Result<()>> {
Box::pin(async move {
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(())
})
}
}