use rustzmq2::prelude::*;
use rustzmq2::{clear_zap_handler, set_zap_handler, ZapRequest, ZapResponse};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
set_zap_handler(|req: ZapRequest| async move {
println!(
"[zap] auth request from {} — user: {:?}",
req.address,
req.username.as_deref().unwrap_or("<none>")
);
match (req.username.as_deref(), req.password.as_deref()) {
(Some("alice"), Some("secret")) => ZapResponse::allow("alice"),
_ => ZapResponse::deny("Unauthorized"),
}
});
let server_task = tokio::spawn(async {
let mut rep = rustzmq2::RepSocket::builder()
.plain_server()
.zap_domain("secure-app")
.build();
rep.bind("tcp://127.0.0.1:5590").await.unwrap();
println!("[server] listening on tcp://127.0.0.1:5590");
for _ in 0..3 {
let msg: String = rep.recv().await.unwrap().try_into().unwrap();
println!("[server] received: {msg}");
rep.send(format!("{msg} — authenticated reply"))
.await
.unwrap();
}
});
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
let mut req = rustzmq2::ReqSocket::builder()
.plain_client("alice", "secret")
.build();
req.connect("tcp://127.0.0.1:5590").await?;
for i in 0..3 {
req.send(format!("hello {i}")).await?;
let reply: String = req.recv().await?.try_into()?;
println!("[client] reply: {reply}");
}
server_task.await?;
clear_zap_handler();
Ok(())
}