Parent

DNSSD::Service

A DNSSD::Service may be used for one DNS-SD call at a time. The service is automatically stopped after calling. A single service can not be reused multiple times.

DNSSD::Service provides the raw DNS-SD functions via the _ variants.

Public Class Methods

new() click to toggle source

Creates a new DNSSD::Service

    # File lib/dnssd/service.rb, line 20
20:   def initialize
21:     @replies = []
22:     @continue = true
23:     @thread = nil
24:     @type = nil
25:   end

Public Instance Methods

add_record(type, data, ttl = 0, flags = 0) click to toggle source

Adds an extra DNS record of type containing data. ttl is in seconds, use 0 for the default value. flags are currently ignored.

Must be called on a service only after #.

Returns the added DNSSD::Record

    # File lib/dnssd/service.rb, line 35
35:   def add_record(type, data, ttl = 0, flags = 0)
36:     raise TypeError, 'must be called after register' unless @type == :register
37:     @records ||= []
38: 
39:     _add_record flags.to_i, type, data, ttl
40:   end
browse(type, domain = nil, flags = 0, interface = DNSSD::InterfaceAny, &block) click to toggle source

Browse for services.

For each service found a DNSSD::Reply object is yielded.

  service = DNSSD::Service.new
  timeout 6 do
    service.browse '_http._tcp' do |r|
      puts "Found HTTP service: #{r.name}"
    end
  rescue Timeout::Error
  end
    # File lib/dnssd/service.rb, line 55
55:   def browse(type, domain = nil, flags = 0, interface = DNSSD::InterfaceAny,
56:              &block)
57:     check_domain domain
58:     interface = DNSSD.interface_index interface unless Integer === interface
59: 
60:     raise DNSSD::Error, 'service in progress' if started?
61: 
62:     @type = :browse
63: 
64:     _browse flags.to_i, interface, type, domain
65: 
66:     process(&block)
67:   end
check_domain(domain) click to toggle source

Raises an ArgumentError if domain is too long including NULL terminator and trailing ’.’

    # File lib/dnssd/service.rb, line 73
73:   def check_domain(domain)
74:     return unless domain
75:     raise ArgumentError, 'domain name string is too long' if
76:       domain.length >= MAX_DOMAIN_NAME - 1
77:   end
enumerate_domains(flags = DNSSD::Flags::BrowseDomains, interface = DNSSD::InterfaceAny, &block) click to toggle source

Enumerate domains available for browsing and registration.

For each domain found a DNSSD::Reply object is passed to block with # set to the enumerated domain.

  available_domains = []
  
  service.enumerate_domains! do |r|
    available_domains << r.domain
    break unless r.flags.more_coming?
  end
  
  p available_domains
     # File lib/dnssd/service.rb, line 94
 94:   def enumerate_domains(flags = DNSSD::Flags::BrowseDomains,
 95:                         interface = DNSSD::InterfaceAny, &block)
 96:     interface = DNSSD.interface_index interface unless Integer === interface
 97: 
 98:     raise DNSSD::Error, 'service in progress' if started?
 99: 
100:     _enumerate_domains flags.to_i, interface
101: 
102:     @type = :enumerate_domains
103: 
104:     process(&block)
105:   end
getaddrinfo(host, protocol = 0, flags = 0, interface = DNSSD::InterfaceAny, &block) click to toggle source

Retrieve address information for host on protocol

  addresses = []
  service.getaddrinfo reply.target do |addrinfo|
    addresses << addrinfo.address
    break unless addrinfo.flags.more_coming?
  end

When using DNSSD on top of the Avahi compatibilty shim you’ll need to setup your /etc/nsswitch.conf correctly. See avahi.org/wiki/AvahiAndUnicastDotLocal for details

     # File lib/dnssd/service.rb, line 120
120:   def getaddrinfo(host, protocol = 0, flags = 0,
121:                   interface = DNSSD::InterfaceAny, &block)
122:     interface = DNSSD.interface_index interface unless Integer === interface
123: 
124:     if respond_to? :_getaddrinfo then
125:       raise DNSSD::Error, 'service in progress' if started?
126: 
127:       _getaddrinfo flags.to_i, interface, protocol, host
128: 
129:       @type = :getaddrinfo
130: 
131:       process(&block)
132:     else
133:       family = case protocol
134:                when IPv4 then Socket::AF_INET
135:                when IPv6 then Socket::AF_INET6
136:                else protocol
137:                end
138: 
139:       addrinfo = Socket.getaddrinfo host, nil, family
140: 
141:       addrinfo.each do |_, _, a_host, ip, _|
142:         sockaddr = Socket.pack_sockaddr_in 0, ip
143:         @replies << DNSSD::Reply::AddrInfo.new(self, 0, 0, a_host, sockaddr, 0)
144:       end
145:     end
146:   end
process() click to toggle source

Yields results from the mDNS daemon, blocking until data is available. Use break or return when you wish to stop receiving results.

The service is automatically stopped after calling this method.

     # File lib/dnssd/service.rb, line 159
159:   def process # :yields: DNSSD::Result
160:     @thread = Thread.current
161: 
162:     while @continue do
163:       _process if @replies.empty?
164:       yield @replies.shift until @replies.empty?
165:     end
166: 
167:     @thread = nil
168: 
169:     self
170:   rescue DNSSD::ServiceNotRunningError
171:     # raised when we jump out of DNSServiceProcess() while it's waiting for a
172:     # response
173:     self
174:   ensure
175:     stop unless stopped?
176:   end
query_record(fullname, record_type, record_class = DNSSD::Record::IN, flags = 0, interface = DNSSD::InterfaceAny, &block) click to toggle source

Retrieves an arbitrary DNS record

fullname is the full name of the resource record. record_type is the type of the resource record (see DNSSD::Resource).

flags may be either DNSSD::Flags::ForceMulticast or DNSSD::Flags::LongLivedQuery

  service.query_record "hostname._afpovertcp._tcp.local",
                       DNSService::Record::SRV do |record|
    p record
  end
     # File lib/dnssd/service.rb, line 192
192:   def query_record(fullname, record_type, record_class = DNSSD::Record::IN,
193:                    flags = 0, interface = DNSSD::InterfaceAny, &block)
194:     interface = DNSSD.interface_index interface unless Integer === interface
195: 
196:     raise DNSSD::Error, 'service in progress' if started?
197: 
198:     _query_record flags.to_i, interface, fullname, record_type, record_class
199: 
200:     @type = :query_record
201: 
202:     process(&block)
203:   end
register(name, type, domain, port, host = nil, text_record = nil, flags = 0, interface = DNSSD::InterfaceAny, &block) click to toggle source

Register a service. A DNSSD::Reply object is passed to the optional block when the registration completes.

  service.register "My Files", "_http._tcp", nil, 8080 do |r|
    puts "successfully registered: #{r.inspect}"
  end
     # File lib/dnssd/service.rb, line 213
213:   def register(name, type, domain, port, host = nil, text_record = nil,
214:                flags = 0, interface = DNSSD::InterfaceAny, &block)
215:     check_domain domain
216:     interface = DNSSD.interface_index interface unless Integer === interface
217:     text_record = text_record.encode if text_record
218: 
219:     raise DNSSD::Error, 'service in progress' if started?
220: 
221:     _register flags.to_i, interface, name, type, domain, host, port,
222:               text_record, &block
223: 
224:     @type = :register
225: 
226:     process(&block) if block
227:   end
resolve(name, type = name.type, domain = name.domain, flags = 0, interface = DNSSD::InterfaceAny, &block) click to toggle source

Resolve a service discovered via #.

name may be either the name of the service found or a DNSSD::Reply from DNSSD::Service#browse. When name is a DNSSD::Reply, type and domain are automatically filled in, otherwise the service type and domain must be supplied.

The service is resolved to a target host name, port number, and text record, all contained in the DNSSD::Reply object passed to the required block.

  service.resolve "foo bar", "_http._tcp", "local" do |r|
    p r
  end
     # File lib/dnssd/service.rb, line 245
245:   def resolve(name, type = name.type, domain = name.domain, flags = 0,
246:               interface = DNSSD::InterfaceAny, &block)
247:     name = name.name if DNSSD::Reply === name
248:     check_domain domain
249:     interface = DNSSD.interface_index interface unless Integer === interface
250: 
251:     raise DNSSD::Error, 'service in progress' if started?
252: 
253:     _resolve flags.to_i, interface, name, type, domain
254: 
255:     @type = :resolve
256: 
257:     process(&block)
258:   end
started?() click to toggle source

Returns true if the service has been started.

     # File lib/dnssd/service.rb, line 263
263:   def started?
264:     not stopped?
265:   end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.