Crates.io | simple-mdns |
lib.rs | simple-mdns |
version | 0.6.2 |
source | src |
created_at | 2021-06-01 01:57:20.621369 |
updated_at | 2024-03-25 21:52:54.308242 |
description | Rust implementation of mDNS for service discovering (DNS-SD) |
homepage | |
repository | https://github.com/balliegojr/simple-dns |
max_upload_size | |
id | 404547 |
size | 117,805 |
Pure Rust implementation for mDNS and DNS-SD protocols
This crate provides two versions of service discovery, the sync version is located in the module sync_discovery
and the async counterpart in async_discovery
.
It is necessary to enable at least one of the features to use service discovery
sync_discovery
moduleasync_discovery
module using tokio runtimeAdvertise registered addresses and query for available instances on the same network.
It is necessary to provide instance and service name
# #[cfg(feature = "sync")] {
use simple_mdns::sync_discovery::ServiceDiscovery;
use simple_mdns::InstanceInformation;
use std::str::FromStr;
let mut discovery = ServiceDiscovery::new(
InstanceInformation::new("a".into()).with_socket_address("192.168.1.22:8090".parse().expect("Invalid socket address")),
"_mysrv._tcp.local",
60
).expect("Failed to start service discovery");
// Removing service from discovery
discovery.remove_service_from_discovery();
# }
One shot resolvers are considered legacy and not fully compliant with the mDNS protocol, but they are handy for service discovery if you have (or need) only one service instance
One shot resolvers or queries send a multicast DNS question to discover available services in the network.
Since mDNS is a well known protocol, you can register your service in any mDNS responder inside your network, and they should be able to reply the requested information about your service.
Query example:
# #[cfg(feature = "sync")] {
use simple_mdns::sync_discovery::OneShotMdnsResolver;
let resolver = OneShotMdnsResolver::new().expect("Failed to create resolver");
// querying for IP Address
let answer = resolver.query_service_address("_myservice._tcp.local").expect("Failed to query service address");
println!("{:?}", answer);
// IpV4Addr or IpV6Addr, depending on what was returned
let answer = resolver.query_service_address_and_port("_myservice._tcp.local").expect("Failed to query service address and port");
println!("{:?}", answer);
// SocketAddr, "127.0.0.1:8080", with a ipv4 or ipv6
# }
In case you don't have a mDNS responder in your network, or for some reason don't want to use the ones available.
This responder will list for any mDNS query in the network via Multicast and will reply only to the resources that were added.
This struct relies on simple-dns
crate and the same must be added as a dependency
# #[cfg(feature = "sync")] {
use simple_mdns::sync_discovery::SimpleMdnsResponder;
use simple_dns::{Name, CLASS, ResourceRecord, rdata::{RData, A, SRV}};
use std::net::Ipv4Addr;
let mut responder = SimpleMdnsResponder::new(10);
let srv_name = Name::new_unchecked("_srvname._tcp.local");
responder.add_resource(ResourceRecord::new(
srv_name.clone(),
CLASS::IN,
10,
RData::A(A { address: Ipv4Addr::LOCALHOST.into() }),
));
responder.add_resource(ResourceRecord::new(
srv_name.clone(),
CLASS::IN,
10,
RData::SRV(SRV {
port: 8080,
priority: 0,
weight: 0,
target: srv_name
})
));
# }
IPV6 is now supported by using the NetworkScope
enum.
# // This is test is marked as no_run because IPV6 is not available in github actions.
# #[cfg(feature = "sync")] {
use simple_mdns::sync_discovery::ServiceDiscovery;
use simple_mdns::{NetworkScope, InstanceInformation};
use std::str::FromStr;
let mut discovery = ServiceDiscovery::new_with_scope(
InstanceInformation::new("a".into()),
"_mysrv._tcp.local",
60,
None,
NetworkScope::V6,
).expect(" Service Name");
# }
Note: It is not tested on MacOS.