Skip to content

Instantly share code, notes, and snippets.

@nickcoutsos
Created November 30, 2013 02:39
Show Gist options
  • Save nickcoutsos/7714711 to your computer and use it in GitHub Desktop.
Save nickcoutsos/7714711 to your computer and use it in GitHub Desktop.
Simplified versions of the pybonjour examples. These use a single event loop for the chained asynchronous callbacks and include some extra comments to explain what's going on.
import select
import sys
from pybonjour import (kDNSServiceErr_NoError,
kDNSServiceFlagsAdd,
DNSServiceResolve,
DNSServiceBrowse,
DNSServiceProcessResult)
regtype = sys.argv[1]
timeout = 5
references = []
def active(ref):
"""Determine whether or not the reference is still open."""
return bool(ref) and ref.fileno() != -1
def on_discover(sdRef, flags, interface, error, name, regtype, domain):
"""Handle discovery of a service (or its disappearance)."""
if error != kDNSServiceErr_NoError:
return
elif not (flags & kDNSServiceFlagsAdd):
print 'Service removed'
return
print 'Service added; resolving'
resolve_sdRef = DNSServiceResolve(
0,
interface,
name,
regtype,
domain,
on_resolve)
references.append(resolve_sdRef)
def on_resolve(sdRef, flags, interface, error, fullname, target, port, txtRecord):
"""Handle resolution of a service."""
if error != kDNSServiceErr_NoError:
raise Exception('Unexpected pybonjour error code: %r' % error)
print 'Resolved service:'
print ' fullname =', fullname
print ' hosttarget =', target
print ' port =', port
sdRef.close()
if __name__ == '__main__':
# Get a reference to browse for services.
browse_sdRef = DNSServiceBrowse(regtype=regtype, callBack=on_discover)
references.append(browse_sdRef)
try:
# Our event loop. Any DNSService references will be polled for updates
# here. When results are available the reference is passed along to
# DNSServiceProcessResult to do whatever internal work is required,
# and then trigger the appropriate callback.
while True:
# Make sure closed references are removed before calling select()
references = filter(active, references)
r, w, x = select.select(references, [], [])
map(DNSServiceProcessResult, r)
except KeyboardInterrupt:
pass
finally:
for ref in references:
ref.close()
import select
import socket
import sys
from pybonjour import (kDNSServiceErr_NoError,
kDNSServiceFlagsAdd,
kDNSServiceType_A,
DNSServiceBrowse,
DNSServiceProcessResult,
DNSServiceQueryRecord,
DNSServiceResolve)
regtype = sys.argv[1]
timeout = 5
references = []
def active(ref):
"""Determine whether or not the reference is still open."""
return bool(ref) and ref.fileno() != -1
def on_discover(sdRef, flags, interface, error, name, regtype, domain):
"""Handle discovery of a service (or its disappearance)."""
if error != kDNSServiceErr_NoError:
return
elif not (flags & kDNSServiceFlagsAdd):
print 'Service removed'
sdRef.close()
return
print 'Service added; resolving'
resolve_sdRef = DNSServiceResolve(
0,
interface,
name,
regtype,
domain,
on_resolve)
references.append(resolve_sdRef)
def on_resolve(sdRef, flags, interface, error, fullname, target, port, txtRecord):
"""Handle resolution of a service."""
if error != kDNSServiceErr_NoError:
raise Exception('Unexpected pybonjour error code: %r' % error)
print 'Resolved service:'
print ' fullname =', fullname
print ' hosttarget =', target
print ' port =', port
sdRef.close()
query_sdRef = DNSServiceQueryRecord(
interfaceIndex=interface,
fullname=target,
rrtype=kDNSServiceType_A,
callBack=on_query)
references.append(query_sdRef)
def on_query(sdRef, flags, interface, error, fullname, rrtype, rrclass, rdata, ttl):
"""Handle query results from a record."""
if error != kDNSServiceErr_NoError:
raise Exception('Unexpected pybonjour error: %r' % error)
print ' IP =', socket.inet_ntoa(rdata)
print ' rrtype =', rrtype
print ' rrclass =', rrclass
print ' rdata =', rdata
print ' ttl =', ttl
sdRef.close()
if __name__ == '__main__':
# Get a reference to browse for services.
browse_sdRef = DNSServiceBrowse(regtype=regtype, callBack=on_discover)
references.append(browse_sdRef)
try:
# Our event loop. Any DNSService references will be polled for updates
# here. When results are available the reference is passed along to
# DNSServiceProcessResult to do whatever internal work is required,
# and then trigger the appropriate callback.
while True:
# Make sure closed references are removed before calling select()
references = filter(active, references)
r, w, x = select.select(references, [], [])
map(DNSServiceProcessResult, r)
except KeyboardInterrupt:
pass
finally:
for ref in references:
ref.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment