use mdns_sd::{ServiceDaemon, ServiceEvent};
fn main() {
env_logger::builder().format_timestamp_millis().init();
let mut service_type = match std::env::args().nth(1) {
Some(arg) => arg,
None => {
print_usage();
return;
}
};
service_type.push_str(".local.");
let should_verify = match std::env::args().nth(2) {
Some(arg) if arg == "--verify" => true,
_ => false,
};
let mdns = ServiceDaemon::new().expect("Failed to create daemon");
let receiver = mdns.browse(&service_type).expect("Failed to browse");
let now = std::time::Instant::now();
while let Ok(event) = receiver.recv() {
match event {
ServiceEvent::ServiceResolved(info) => {
println!(
"At {:?}: Resolved a new service: {}\n host: {}\n port: {}",
now.elapsed(),
info.fullname,
info.host,
info.port,
);
let mut found_ipv4 = false;
for addr in info.addresses.iter() {
println!(" Address: {addr}");
if addr.is_ipv4() {
found_ipv4 = true;
}
}
for prop in info.txt_properties.iter() {
println!(" Property: {}", prop);
}
if should_verify && found_ipv4 {
println!("Will verify after 3 seconds...");
std::thread::sleep(std::time::Duration::from_secs(3));
let instance_fullname = info.fullname;
let timeout = std::time::Duration::from_secs(2);
if let Err(e) = mdns.verify(instance_fullname, timeout) {
println!("Verify failed: {}", e);
} else {
println!("Verify started");
}
}
}
ServiceEvent::ServiceRemoved(service_type, fullname) => {
println!(
"At {:?}: ** service removed **: {service_type}: {fullname}",
now.elapsed(),
);
}
other_event => {
println!("At {:?}: {:?}", now.elapsed(), &other_event);
}
}
}
}
fn print_usage() {
println!("Usage: cargo run --example query <service_type_without_domain_postfix> [--verify]");
println!("Example: ");
println!("cargo run --example query _my-service._udp");
println!();
println!("Options:");
println!("--verify: make the client attempt to verify IPv4 addresses of resolved services.");
println!();
println!("You can also do a meta-query per RFC 6763 to find which services are available:");
println!("cargo run --example query _services._dns-sd._udp");
}