Routers

Most apps will use more than one protocol. A router let’s you stack protocols on top of iroh's peer-to-peer connections. Routers handle the accept side of an iroh endpoint, but the connection initiation side is still handled by the protocol instance itself.

Since we've already set up a router when adding iroh blobs, we can add another protocol to the router with a few lines of code. Let's add iroh gossip, first by installing the dependency:

cargo add iroh-gossip

Then we can setup gossip & add it to our router:

use iroh::{protocol::Router, Endpoint};
use iroh_blobs::{net_protocol::Blobs, util::local_pool::LocalPool};
use iroh_gossip::{net::Gossip, ALPN};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let endpoint = Endpoint::builder().discovery_n0().bind().await?;

    let local_pool = LocalPool::default();
    let blobs = Blobs::memory().build(local_pool.handle(), &endpoint);

    let gossip = Gossip::builder().spawn(endpoint.clone()).await?;

    // build the router
    let router = Router::builder(endpoint)
        .accept(iroh_blobs::ALPN, blobs.clone())
        .accept(iroh_gossip::ALPN, gossip.clone())
        .spawn()
        .await?;

    router.shutdown().await?;
    drop(local_pool);
    Ok(())
}

The amount of code is small, but the conceptual shift is a nice-to-have, wrapping an endpoint in a router makes the design intent of iroh clear: set up an endpoint, pull in protocols, feed them to the router, and bind your way to glory.