我正在尝试移植一些目前使用Avahi原始dbus接口的代码来使用Avahi gobject接口(通过python的gobject内省)。
我已经获得了ServiceBrowser,但我无法让ServiceResolver工作。这是我的代码:
#!/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()
示例输出:
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
在我按下ctrl-c之前,我让它运行了大约1分钟。如您所见,我正在调用ServiceResolver,但sr_found和sr_failure方法永远不会被调用。我怎样才能让它发挥作用?
(我在http://code.ohloh.net/上找不到任何其他代码,所以我怀疑我可能是第一个尝试这样做的人)
答案 0 :(得分:0)
基本上你的代码工作正常。唯一的问题是reference counting。
当python解释器到达sb_new_service()
的末尾时,它将删除不再被引用的所有对象。由于您已将service_resolver
指定为局部变量,因此也将删除此对象。
为防止这种情况发生,您只需将service_resolver
添加到(全局)解析器列表中,如下所示:
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)
然后你的代码应该可以正常工作。