[avahi] Registering Service Subtype?

Mark K. Gardner mkg at vt.edu
Wed Nov 5 11:55:37 PST 2008


Background: I am trying to make a master/worker application
autoconfigure using zeroconf. I plan to have the master register a
service that the workers can lookup and the workers register a service
that the master can lookup. In this application, masters can also do
work so I am attempting to register a base service and then
distinguish masters from workers by using subtypes.

The code below, excluding the AddServiceSubtype call, registers the
master service successfully:

$ example.py &
$ avahi-browse -t "_demo._tcp"
+ eth0 IPv4 Example Service       _demo._tcp   local

Adding the AddServiceSubtype call causes an exception:

Traceback (most recent call last):
  File "./example.py", line 62, in ?
    service = publish(name=NAME, stype=STYPE, port=PORT,
		subtype=SUB_STYPE)
  File "./example.py", line 52, in publish
    subtype)
  File "/var/lib/python-support/python2.4/dbus/proxies.py", line 102,
	in __call__
    reply_message =
		self._connection.send_with_reply_and_block(message, timeout)
  File "dbus_bindings.pyx", line 455, in
	dbus_bindings.Connection.send_with_reply_and_block
dbus_bindings.DBusException: Invalid service subtype

=== BEGIN example.py ===
#!/usr/bin/python

NAME  = 'Example Service'
STYPE = '_demo._tcp'
PORT  = 6583

SUB_NAME  = '%s (sub-service)' % NAME
SUB_STYPE = '_subservice'

DEBUGGING = True

import avahi
import dbus
import gobject
import sys

def debug(message):
    if DEBUGGING:
        sys.stderr.write(message);
        sys.stderr.write('\n');
        sys.stderr.flush();


def publish(name, stype, port, subtype=None, domain='', host='', text=''):
    bus = dbus.SystemBus()
    server = dbus.Interface(
        bus.get_object(avahi.DBUS_NAME,
                            avahi.DBUS_PATH_SERVER),
        avahi.DBUS_INTERFACE_SERVER)
    group = dbus.Interface(
        bus.get_object(avahi.DBUS_NAME,
                            server.EntryGroupNew()),
        avahi.DBUS_INTERFACE_ENTRY_GROUP)
    group.connect_to_signal('StateChanged',
                            lambda state, status:
                                _changeState(name, stype,
                                         state, status))
    group.AddService(avahi.IF_UNSPEC,
                     avahi.PROTO_UNSPEC,
                     dbus.UInt32(0),
                     name, stype, domain, host,
                     dbus.UInt16(port),
                     text)
    # Code added for subservice:
    if subtype:
        group.AddServiceSubtype(avahi.IF_UNSPEC,
                                avahi.PROTO_UNSPEC,
                                dbus.UInt32(0),
                                name, stype, domain,
                                subtype)
    # End
    group.Commit()

def _changeState(name, stype, state, status=None):
    if state == avahi.ENTRY_GROUP_ESTABLISHED:
        debug('Service %s of type %s established.' % (name, stype))
    elif state == avahi.ENTRY_GROUP_COLLISION:
        unpublish(name, stype)


#service = publish(name=NAME, stype=STYPE, port=PORT)
service = publish(name=NAME, stype=STYPE, port=PORT, subtype=SUB_STYPE)

eventLoop = gobject.MainLoop()
try:
    eventLoop.run()
except KeyboardInterrupt:
    pass
=== END ===

Note: I am using Debian Etch and the versions of the packages are

  python2.4       2.4.4-3+etch1
  python-dbus     0.71-3
  python-avahi    0.6.16-3etch1
  python-gtk2     2.8.6-8
  libavahi-core4  0.6.16-3etch1

Would anyone please enlighten me as to what I am doing wrong? Do you
have an example of how to register a subtype?

Once I can register a subtype, how can I query and get all current
services of type _demo._tcp and iterate through them all so I can do
type specific things with each one?

Mark

-- 
Mark Gardner
Network Research Manager
Communications Network Services
Virginia Tech
-- 


More information about the avahi mailing list