1use std::time::{Duration, Instant};
8
9use log::info;
10use mdns_sd::{ServiceDaemon, ServiceEvent, ServiceInfo};
11
12use flowcore::errors::{bail, Result};
13
14use crate::services::FLOW_SERVICE_TYPE;
15
16const DEFAULT_DISCOVERY_TIMEOUT: Duration = Duration::from_secs(30);
17
18pub fn enable_service_discovery(name: &str, service_port: u16) -> Result<ServiceDaemon> {
27 let mdns = ServiceDaemon::new().map_err(|e| format!("Could not create mDNS daemon: {e}"))?;
28
29 let service_hostname = format!("{name}.local.");
30
31 let service_info = ServiceInfo::new(
32 FLOW_SERVICE_TYPE,
33 name,
34 &service_hostname,
35 "",
36 service_port,
37 None,
38 )
39 .map_err(|e| format!("Could not create mDNS ServiceInfo: {e}"))?
40 .enable_addr_auto();
41
42 mdns.register(service_info)
43 .map_err(|e| format!("Could not register mDNS service: {e}"))?;
44
45 info!("mDNS service registered: '{name}' on port {service_port}");
46
47 Ok(mdns)
48}
49
50pub fn discover_service(name: &str) -> Result<String> {
59 let mdns = ServiceDaemon::new().map_err(|e| format!("Could not create mDNS daemon: {e}"))?;
60
61 let receiver = mdns
62 .browse(FLOW_SERVICE_TYPE)
63 .map_err(|e| format!("Could not browse for mDNS services: {e}"))?;
64
65 let full_name_suffix = format!(".{FLOW_SERVICE_TYPE}");
66 let start = Instant::now();
67
68 loop {
69 if start.elapsed() > DEFAULT_DISCOVERY_TIMEOUT {
70 mdns.shutdown().ok();
71 bail!(format!(
72 "mDNS discovery timed out after {}s for '{name}'",
73 DEFAULT_DISCOVERY_TIMEOUT.as_secs()
74 ));
75 }
76
77 if let Ok(ServiceEvent::ServiceResolved(info)) =
78 receiver.recv_timeout(Duration::from_millis(500))
79 {
80 let instance = info
81 .get_fullname()
82 .strip_suffix(&full_name_suffix)
83 .unwrap_or(info.get_fullname());
84
85 if instance == name {
86 let port = info.get_port();
87 if let Some(addr) = info.get_addresses_v4().into_iter().next() {
88 let address = format!("{addr}:{port}");
89 info!("Discovered mDNS service '{name}' at {address}");
90 mdns.shutdown().ok();
91 return Ok(address);
92 }
93 }
94 }
95 }
96}