Domanda

I'm trying to port some code, that currently uses the Avahi raw dbus interface, to using the Avahi gobject interface (via gobject introspection from python.)

I have gotten the ServiceBrowser, but I can't get the ServiceResolver to work. Here is my code:

#!/usr/bin/env python

import logging

from gi.repository import Avahi

logging.basicConfig(level=logging.DEBUG)
ac_log = logging.getLogger('Avahi.Client')
sb_log = logging.getLogger('Avahi.ServiceBrowser')
sr_log = logging.getLogger('Avahi.ServiceResolver')

def ac_state_changed(client, state):
    ac_log.debug('state_changed: {}'.format(state))

avahi_client = Avahi.Client(flags=0,)
avahi_client.connect('state-changed', ac_state_changed)
avahi_client.start()

def sb_new_service(browser, interface, protocol, name, type, domain, flags ):
    sb_log.debug('new: {}'.format(name))
    if not (flags & Avahi.LookupResultFlags.GA_LOOKUP_RESULT_LOCAL):
        sb_log.debug('resolving: {}'.format(name))
        service_resolver = Avahi.ServiceResolver(
            interface=interface,
            protocol=protocol,
            name=name,
            type=type,
            domain=domain,
            aprotocol=Avahi.Protocol.GA_PROTOCOL_UNSPEC,
            flags=0,)
        service_resolver.connect('found', sr_found)
        service_resolver.connect('failure', sr_failure)
        service_resolver.attach(avahi_client)

def sb_all_for_now(*args):
    sb_log.debug('all_for_now')
    seen_all = True

def sb_failure(*args):
    sb_log.error('failure: {}'.format(args))

def sr_found(*args):
    sr_log.debug('found: {}'.format(args))

def sr_failure(*args):
    sr_log.error('failure: {}'.format(args))


service_browser = Avahi.ServiceBrowser(
    domain='local',
    flags=0,
    interface=-1,
    protocol=Avahi.Protocol.GA_PROTOCOL_UNSPEC,
    type='_workstation._tcp')

service_browser.connect("new_service", sb_new_service)
service_browser.connect("failure", sb_failure)
service_browser.attach(avahi_client)


from gi.repository import GObject

mainloop = GObject.MainLoop()
mainloop.run()

example output:

DEBUG:Avahi.Client:state_changed: <enum GA_CLIENT_STATE_S_RUNNING of type GaClientState>
DEBUG:Avahi.ServiceBrowser:new: Mobi [d8:d3:85:e8:26:3d]
DEBUG:Avahi.ServiceBrowser:resolving: Mobi [d8:d3:85:e8:26:3d]
DEBUG:Avahi.ServiceBrowser:new: garyvdm [00:1d:09:a5:10:54]
DEBUG:Avahi.ServiceBrowser:new: noddy [00:15:c5:c6:46:4b]
DEBUG:Avahi.ServiceBrowser:resolving: noddy [00:15:c5:c6:46:4b]
DEBUG:Avahi.ServiceBrowser:new: crack [00:1c:26:20:e0:1d]
DEBUG:Avahi.ServiceBrowser:resolving: crack [00:1c:26:20:e0:1d]
DEBUG:Avahi.ServiceBrowser:new: opium [00:1d:09:c1:ed:cf]
DEBUG:Avahi.ServiceBrowser:resolving: opium [00:1d:09:c1:ed:cf]
DEBUG:Avahi.ServiceBrowser:new: gerard-vm [00:0c:29:d0:2a:af]
DEBUG:Avahi.ServiceBrowser:resolving: gerard-vm [00:0c:29:d0:2a:af]
DEBUG:Avahi.ServiceBrowser:all_for_now
^CTraceback (most recent call last):
  File "pacshare/xfer.py", line 65, in <module>
    mainloop.run()
KeyboardInterrupt

I left it running for about 1min before I pressed ctrl-c. As you can see, I'm calling the ServiceResolver, but the sr_found and sr_failure methods never get called. How can I get this to work?

(I can't find any other code that does this on http://code.ohloh.net/, so I suspect I may be the first person trying to do this)

È stato utile?

Soluzione

Basically your code works just right. The only problem it has is reference counting.

When the python interpreter reaches the end of sb_new_service(), it will delete all objects that are no longer being referenced. As you have specified service_resolver as a local variable, this object will also be deleted. To prevent this from happening, you could just add service_resolver to a (global) list of resolvers like this:

resolvers = []

def sb_new_service(browser, interface, protocol, name, type, domain, flags ):
    sb_log.debug('new: {}'.format(name))
    if not (flags & Avahi.LookupResultFlags.GA_LOOKUP_RESULT_LOCAL):
        sb_log.debug('resolving: {}'.format(name))
        service_resolver = Avahi.ServiceResolver(
            interface=interface,
            protocol=protocol,
            name=name,
            type=type,
            domain=domain,
            aprotocol=Avahi.Protocol.GA_PROTOCOL_UNSPEC,
            flags=0,)
        service_resolver.connect('found', sr_found)
        service_resolver.connect('failure', sr_failure)
        service_resolver.attach(avahi_client)
        global resolvers
        resolvers.append(service_resolver)

Then your code should work fine.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top