use nym_sdk::mixnet;
use std::time::Duration;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
const IDLE_TIMEOUT: Duration = Duration::from_secs(2);
const WAIT_TIMEOUT: Duration = Duration::from_secs(60);
#[tokio::main]
async fn main() {
nym_bin_common::logging::setup_tracing_logger();
let mut client = mixnet::MixnetClientBuilder::new_ephemeral()
.with_stream_idle_timeout(IDLE_TIMEOUT)
.build()
.unwrap()
.connect_to_mixnet()
.await
.unwrap();
let our_address = *client.nym_address();
println!("Client address: {our_address}");
let mut listener = client.listener().unwrap();
let mut outbound = client.open_stream(our_address, None).await.unwrap();
println!("Opened outbound stream: {}", outbound.id());
let mut inbound = tokio::time::timeout(WAIT_TIMEOUT, listener.accept())
.await
.expect("timed out waiting for accept")
.expect("listener shut down");
println!("Accepted inbound stream: {}", inbound.id());
let msg = b"hello from idle timeout example";
outbound.write_all(msg).await.unwrap();
outbound.flush().await.unwrap();
let mut buf = vec![0u8; 1024];
let n = tokio::time::timeout(WAIT_TIMEOUT, inbound.read(&mut buf))
.await
.expect("timed out reading")
.expect("read failed");
println!("Received: {:?}", String::from_utf8_lossy(&buf[..n]));
assert_eq!(&buf[..n], msg);
println!(
"\nStream is idle. Waiting {}s for cleanup...",
IDLE_TIMEOUT.as_secs()
);
tokio::time::sleep(IDLE_TIMEOUT + Duration::from_secs(2)).await;
let n = inbound.read(&mut buf).await.expect("read failed");
if n == 0 {
println!("Inbound stream returned EOF — cleaned up by idle timeout.");
} else {
println!("Unexpected: got {n} bytes after idle timeout");
}
drop(outbound);
drop(inbound);
client.disconnect().await;
}