[omg] GUI, mDNS, list games on client start
This commit is contained in:
9
crates/lanspread-mdns/Cargo.toml
Normal file
9
crates/lanspread-mdns/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "lanspread-mdns"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
mdns-sd = "0.11"
|
||||
eyre = { workspace = true }
|
||||
tracing = { workspace = true }
|
86
crates/lanspread-mdns/src/lib.rs
Normal file
86
crates/lanspread-mdns/src/lib.rs
Normal file
@ -0,0 +1,86 @@
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use eyre::bail;
|
||||
pub use mdns_sd::DaemonEvent;
|
||||
use mdns_sd::{Receiver, ServiceDaemon, ServiceEvent, ServiceInfo};
|
||||
|
||||
pub const LANSPREAD_SERVICE_TYPE: &str = "_lanspread._udp.local.";
|
||||
pub const LANSPREAD_INSTANCE_NAME: &str = "softlan";
|
||||
|
||||
pub struct MdnsAdvertiser {
|
||||
daemon: ServiceDaemon,
|
||||
service_info: ServiceInfo,
|
||||
pub monitor: Receiver<DaemonEvent>,
|
||||
}
|
||||
|
||||
impl MdnsAdvertiser {
|
||||
pub fn new(service_type: &str, instance_name: &str, address: SocketAddr) -> eyre::Result<Self> {
|
||||
let host_name = format!("{}.local.", address.ip());
|
||||
let daemon = ServiceDaemon::new()?;
|
||||
let service_info = ServiceInfo::new(
|
||||
service_type,
|
||||
instance_name,
|
||||
&host_name,
|
||||
address.ip(),
|
||||
address.port(),
|
||||
None,
|
||||
)?;
|
||||
|
||||
let monitor = daemon.monitor()?;
|
||||
|
||||
// Register the service
|
||||
daemon.register(service_info.clone())?;
|
||||
|
||||
Ok(Self {
|
||||
daemon,
|
||||
service_info,
|
||||
monitor,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for MdnsAdvertiser {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.daemon.unregister(self.service_info.get_fullname());
|
||||
let _ = self.daemon.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn discover_service(
|
||||
service_type: &str,
|
||||
instance_name: Option<&str>,
|
||||
) -> eyre::Result<SocketAddr> {
|
||||
let mdns = ServiceDaemon::new().expect("Failed to create mDNS daemon.");
|
||||
|
||||
let receiver = mdns.browse(service_type)?;
|
||||
|
||||
while let Ok(event) = receiver.recv() {
|
||||
match event {
|
||||
ServiceEvent::ServiceResolved(info) => {
|
||||
tracing::trace!(?info, "mdns ServiceResolved event");
|
||||
|
||||
if let Some(instance_name) = instance_name {
|
||||
if info.get_fullname() != format!("{}.{}", instance_name, service_type) {
|
||||
tracing::warn!(
|
||||
"Found service with wrong instance name: {} (expected: {})",
|
||||
info.get_fullname(),
|
||||
instance_name,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(address) = info.get_addresses().iter().next() {
|
||||
tracing::info!("Found server at {}:{}", address, info.get_port());
|
||||
return Ok((*address, info.get_port()).into());
|
||||
}
|
||||
|
||||
tracing::error!(?info, "No address found in mDNS response.");
|
||||
}
|
||||
other_event => {
|
||||
tracing::trace!(?other_event, "mdns unrelated event");
|
||||
}
|
||||
}
|
||||
}
|
||||
bail!("No server found.")
|
||||
}
|
Reference in New Issue
Block a user