Module: ZeroConf
- Defined in:
- lib/zeroconf.rb,
lib/zeroconf/utils.rb,
lib/zeroconf/client.rb,
lib/zeroconf/browser.rb,
lib/zeroconf/service.rb,
lib/zeroconf/version.rb,
lib/zeroconf/resolver.rb,
lib/zeroconf/discoverer.rb
Defined Under Namespace
Modules: MDNS, Utils Classes: A, ANY, Browser, Client, Discoverer, PTR, Resolver, SRV, Service
Constant Summary collapse
- MDNS_CACHE_FLUSH =
0x8000
- VERSION =
"1.0.1"
Class Method Summary collapse
-
.browse(name, interfaces: self.interfaces, timeout: 3, &blk) ⇒ Object
ZeroConf.browse.
-
.discover(interfaces: self.interfaces, timeout: 3, &blk) ⇒ Object
ZeroConf.discover.
-
.find_addrinfos(name, interfaces: self.interfaces, timeout: 3) ⇒ Object
Get a list tuples with host name and Addrinfo objects for a particular service name.
-
.find_services(interfaces: self.interfaces, timeout: 3) ⇒ Object
ZeroConf.find_services.
- .interfaces ⇒ Object
- .resolve(name, interfaces: self.interfaces, timeout: 3, &blk) ⇒ Object
- .service(service, service_port, hostname = Socket.gethostname, service_interfaces: self.service_interfaces, text: [""]) ⇒ Object
- .service_interfaces ⇒ Object
Class Method Details
.browse(name, interfaces: self.interfaces, timeout: 3, &blk) ⇒ Object
ZeroConf.browse
Call this method to find server information for a particular service. For example, to find server information for servers advertising ‘_elg._tcp.local`, do this:
ZeroConf.browse("_elg._tcp.local") { |r| p r }
Yields info it finds to the provided block as it is received. Pass a list of interfaces you want to use, or just use the default. Also takes a timeout parameter to specify the length of the timeout.
26 27 28 29 |
# File 'lib/zeroconf.rb', line 26 def self.browse name, interfaces: self.interfaces, timeout: 3, &blk browser = ZeroConf::Browser.new(name, interfaces:) browser.run(timeout:, &blk) end |
.discover(interfaces: self.interfaces, timeout: 3, &blk) ⇒ Object
ZeroConf.discover
Call this method to discover services on your network! Yields services it finds to the provided block as it finds them. Pass a list of interfaces you want to use, or just use the default. Also takes a timeout parameter to specify the length of the timeout.
110 111 112 113 |
# File 'lib/zeroconf.rb', line 110 def self.discover interfaces: self.interfaces, timeout: 3, &blk discoverer = ZeroConf::Discoverer.new(interfaces:) discoverer.run(timeout:, &blk) end |
.find_addrinfos(name, interfaces: self.interfaces, timeout: 3) ⇒ Object
Get a list tuples with host name and Addrinfo objects for a particular service name.
For example:
pp ZeroConf.find_addrinfos("_elg._tcp.local")
# [["elgato-key-light-2d93.local", #<Addrinfo: 10.0.1.249:9123 (elgato-key-light-2d93.local)>],
# ["elgato-key-light-2d93.local", #<Addrinfo: [fe80::3e6a:9dff:fe19:b313]:9123 (elgato-key-light-2d93.local)>],
# ["elgato-key-light-48c6.local", #<Addrinfo: 10.0.1.151:9123 (elgato-key-light-48c6.local)>],
# ["elgato-key-light-48c6.local", #<Addrinfo: [fe80::3e6a:9dff:fe19:3a99]:9123 (elgato-key-light-48c6.local)>]]
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/zeroconf.rb', line 43 def self.find_addrinfos name, interfaces: self.interfaces, timeout: 3 browse(name, interfaces:, timeout:).flat_map { |r| host = nil port = nil ipv4 = [] ipv6 = [] r.additional.each { |name, ttl, data| case data when Resolv::DNS::Resource::IN::SRV host = data.target.to_s port = data.port when Resolv::DNS::Resource::IN::A ipv4 << data.address when Resolv::DNS::Resource::IN::AAAA ipv6 << data.address end } ipv4.map { |x| [host, ["AF_INET", port, host, x.to_s]] } + ipv6.map { |x| [host, ["AF_INET6", port, host, x.to_s]] } }.uniq.map { |host, x| [host, Addrinfo.new(x)] } end |
.find_services(interfaces: self.interfaces, timeout: 3) ⇒ Object
ZeroConf.find_services
Get a list of services being advertised on the network!
This method will yield the services as it finds them, or it will return a list of unique service names if no block is given.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/zeroconf.rb', line 85 def self.find_services interfaces: self.interfaces, timeout: 3 if block_given? discover(interfaces:, timeout:) do |res| res.answer.map(&:last).map(&:name).map(&:to_s).each { yield _1 } end else discover(interfaces:, timeout:) .flat_map(&:answer) .map(&:last) .map(&:name) .map(&:to_s) .uniq end end |
.interfaces ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/zeroconf.rb', line 115 def self.interfaces addrs = Socket.getifaddrs addrs.select { |ifa| addr = ifa.addr addr && (ifa.flags & Socket::IFF_UP > 0) && # must be up (ifa.flags & Socket::IFF_MULTICAST > 0) && # must have multicast (ifa.flags & Socket::IFF_POINTOPOINT == 0) && # must not be pointopoint (ifa.flags & Socket::IFF_LOOPBACK == 0) && # must not be loopback (addr.ipv4? || # must be ipv4 *or* (addr.ipv6? && !addr.ipv6_linklocal?)) # must be ipv6 and not link local } end |
.resolve(name, interfaces: self.interfaces, timeout: 3, &blk) ⇒ Object
65 66 67 68 |
# File 'lib/zeroconf.rb', line 65 def self.resolve name, interfaces: self.interfaces, timeout: 3, &blk resolver = ZeroConf::Resolver.new(name, interfaces:) resolver.run(timeout:, &blk) end |
.service(service, service_port, hostname = Socket.gethostname, service_interfaces: self.service_interfaces, text: [""]) ⇒ Object
70 71 72 73 |
# File 'lib/zeroconf.rb', line 70 def self.service service, service_port, hostname = Socket.gethostname, service_interfaces: self.service_interfaces, text: [""] s = Service.new(service, service_port, hostname, service_interfaces:, text:) s.start end |
.service_interfaces ⇒ Object
129 130 131 132 |
# File 'lib/zeroconf.rb', line 129 def self.service_interfaces ipv4, ipv6 = interfaces.partition { |ifa| ifa.addr.ipv4? } [ipv4.first, ipv6&.first].compact end |