diff --git a/iroh/examples/custom-protocol.rs b/iroh/examples/custom-protocol.rs index 6d9be32bae..4ed0de72ac 100644 --- a/iroh/examples/custom-protocol.rs +++ b/iroh/examples/custom-protocol.rs @@ -64,40 +64,40 @@ struct ExampleProto { } impl Protocol for ExampleProto { - fn accept(self: Arc, conn: Connecting) -> BoxedFuture> { + fn accept(self: Arc, connecting: Connecting) -> BoxedFuture> { Box::pin(async move { - let conn = conn.await?; - let remote_node_id = get_remote_node_id(&conn)?; - println!("accepted connection from {remote_node_id}"); - let mut send_stream = conn.open_uni().await?; - // not that this is something that you wanted to do, but let's create a new blob for each - // incoming connection. this could be any mechanism, but we want to demonstrate how to use a - // custom protocol together with built-in iroh functionality - let content = format!("this blob is created for my beloved peer {remote_node_id} ♥"); + let connection = connecting.await?; + let peer = get_remote_node_id(&connection)?; + println!("accepted connection from {peer}"); + let mut send_stream = connection.open_uni().await?; + // Let's create a new blob for each incoming connection. + // This functions as an example of using existing iroh functionality within a protocol + // (you likely don't want to create a new blob for each connection for real) + let content = format!("this blob is created for my beloved peer {peer} ♥"); let hash = self .node .blobs() .add_bytes(content.as_bytes().to_vec()) .await?; - // send the hash over our custom proto + // Send the hash over our custom protocol. send_stream.write_all(hash.hash.as_bytes()).await?; send_stream.finish().await?; - println!("closing connection from {remote_node_id}"); + println!("closing connection from {peer}"); Ok(()) }) } } impl ExampleProto { - fn build(node: Node) -> Arc { + pub fn build(node: Node) -> Arc { Arc::new(Self { node }) } - fn get_from_node(node: &Node, alpn: &'static [u8]) -> Option> { + pub fn get_from_node(node: &Node, alpn: &'static [u8]) -> Option> { node.get_protocol::>(alpn) } - async fn connect(&self, remote_node_id: NodeId) -> Result<()> { + pub async fn connect(&self, remote_node_id: NodeId) -> Result<()> { println!("our node id: {}", self.node.node_id()); println!("connecting to {remote_node_id}"); let conn = self @@ -122,8 +122,8 @@ impl ExampleProto { } } -// set the RUST_LOG env var to one of {debug,info,warn} to see logging info -pub fn setup_logging() { +/// Set the RUST_LOG env var to one of {debug,info,warn} to see logging. +fn setup_logging() { tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(std::io::stderr)) .with(EnvFilter::from_default_env()) diff --git a/iroh/src/node/builder.rs b/iroh/src/node/builder.rs index 310241d63e..a273d60cbc 100644 --- a/iroh/src/node/builder.rs +++ b/iroh/src/node/builder.rs @@ -7,7 +7,7 @@ use std::{ }; use anyhow::{bail, Context, Result}; -use futures_lite::{future::Boxed, StreamExt}; +use futures_lite::{future::Boxed as BoxedFuture, StreamExt}; use iroh_base::key::SecretKey; use iroh_blobs::{ downloader::Downloader, @@ -61,7 +61,7 @@ const MAX_STREAMS: u64 = 10; type ProtocolBuilders = Vec<( &'static [u8], - Box) -> Boxed>> + Send + 'static>, + Box) -> BoxedFuture>> + Send + 'static>, )>; /// Storage backend for documents. @@ -386,33 +386,47 @@ where /// the cast automatically, so usually you will have to cast manually: /// /// ```rust + /// # use std::sync::Arc; /// # use anyhow::Result; /// # use futures_lite::future::Boxed as BoxedFuture; + /// # use iroh::{node::{Node, Protocol}, net::endpoint::Connecting}; + /// # + /// # #[tokio::main] + /// # async fn main() -> Result<()> { /// - /// const MY_ALPN: &[u8] = "my-protocol/1"; + /// const MY_ALPN: &[u8] = b"my-protocol/1"; /// /// #[derive(Debug)] /// struct MyProtocol; /// /// impl Protocol for MyProtocol { /// fn accept(self: Arc, conn: Connecting) -> BoxedFuture> { - /// todo!() + /// todo!(); /// } /// } /// - /// let node = Node::memory().accept(MY_ALPN |_node| Box::pin(async move { - /// let protocol = MyProtocol; - /// let protocol: Arc = Arc::new(protocol); - /// Ok(protocol) - /// })) - /// + /// let node = Node::memory() + /// .accept(MY_ALPN, |_node| { + /// Box::pin(async move { + /// let protocol = MyProtocol; + /// let protocol: Arc = Arc::new(protocol); + /// Ok(protocol) + /// }) + /// }) + /// .spawn() + /// .await?; + /// # node.shutdown().await?; + /// # Ok(()) + /// # } /// ``` /// /// pub fn accept( mut self, alpn: &'static [u8], - protocol_builder: impl FnOnce(Node) -> Boxed>> + Send + 'static, + protocol_builder: impl FnOnce(Node) -> BoxedFuture>> + + Send + + 'static, ) -> Self { self.protocols.push((alpn, Box::new(protocol_builder))); self