Expand description
A small and safe library for Multicast DNS-SD (Service Discovery).
This library creates one new thread to run a mDNS daemon, and exposes
its API that interacts with the daemon via a
crossbeam-channel.
For example, a client querying (browsing) a service behaves like this:
Client <channel> mDNS daemon thread
| | starts its run-loop.
| --- Browse --> |
| | detects services
| | finds service instance A
| <-- Found A -- |
| ... | resolves service A
| <-- Resolved A -- |
| ... |All commands in the public API are sent to the daemon using the unblocking try_send()
so that the caller can use it with both sync and async code, with no dependency on any
particular async runtimes.
Usage
The user starts with creating a daemon by calling ServiceDaemon::new().
Then as a mDNS querier, the user would call browse to
search for services, and/or as a mDNS responder, call register
to publish (i.e. announce) its own service. And, the daemon type can be cloned and passed
around between threads.
Example: a client querying for a service type.
use mdns_sd::{ServiceDaemon, ServiceEvent};
// Create a daemon
let mdns = ServiceDaemon::new().expect("Failed to create daemon");
// Browse for a service type.
let service_type = "_mdns-sd-my-test._udp.local.";
let receiver = mdns.browse(service_type).expect("Failed to browse");
// Receive the browse events in sync or async. Here is
// an example of using a thread. Users can call `receiver.try_recv()`
// if running in async environment.
std::thread::spawn(move || {
while let Ok(event) = receiver.recv() {
match (event) {
ServiceEvent::ServiceResolved(info) => {
println!("Resolved a new service: {}", info.get_fullname());
}
other_event => {
println!("Received other event: {:?}", &other_event);
}
}
}
});Example: a server publishs a service and responds to queries.
use mdns_sd::{ServiceDaemon, ServiceInfo};
use std::collections::HashMap;
// Create a daemon
let mdns = ServiceDaemon::new().expect("Failed to create daemon");
// Create a service info.
let service_type = "_mdns-sd-my-test._udp.local.";
let instance_name = "my_instance";
let host_ipv4 = "192.168.1.12";
let host_name = "192.168.1.12.local.";
let port = 5200;
let mut properties = HashMap::new();
properties.insert("property_1".to_string(), "test".to_string());
properties.insert("property_2".to_string(), "1234".to_string());
let my_service = ServiceInfo::new(
service_type,
instance_name,
host_name,
host_ipv4,
port,
Some(properties),
);
// Register with the daemon, which publishs the service.
mdns.register(my_service).expect("Failed to register our service");Limitations
This implementation is based on the following RFCs:
We focus on the common use cases at first, and currently have the following limitations:
- Only support IPv4, not IPv6.
- Only support multicast, not unicast send/recv.
- Only tested on Linux and MacOS, not on Windows or other OSes.
Structs
A daemon thread for mDNS
Complete info about a Service Instance.
Enums
A basic error type from this library.
All possible events sent to the client from the daemon.
Response status code for the service unregister call.
