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
flume channel. The channel supports
both recv() and recv_async().
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.recv_async().await`
// 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 properties = [("property_1", "test"), ("property_2", "1234")];
let my_service = ServiceInfo::new(
service_type,
instance_name,
host_name,
host_ipv4,
port,
&properties[..],
).unwrap();
// Register with the daemon, which publishes 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 support 32-bit or bigger platforms, not 16-bit platforms.
Structs
- A handler to receive messages from ServiceDaemon. Re-export from
flumecrate. The receiving end of a channel. - A daemon thread for mDNS
- Complete info about a Service Instance.
- Represents properties in a TXT record.
- Represents a property in a TXT record.
Enums
- Some notable events from the daemon besides
ServiceEvent. These events are expected to happen infrequently. - A basic error type from this library.
- All possible events sent to the client from the daemon regarding service discovery.
- Response status code for the service
unregistercall.
Constants
- The default max length of the service name without domain, not including the leading underscore (
_). It is set to 15 per RFC 6763 section 7.2.
Traits
- This trait allows for parsing an input into a set of one or multiple
Ipv4Addr. - This trait allows for converting inputs into
TxtProperties.
Type Definitions
- The metrics is a HashMap of (name_key, i64_value). The main purpose is to help monitoring the mDNS packet traffic.
- One and only
Resulttype from this library crate.