2013-03-21 2 views
2

현재 사용할 수있는 특정 유형의 avahi 서비스 목록을 제공하는 클래스가 필요합니다. 그러므로 나는 각각의 스레드에 gobject.MainLoop() (23-25 ​​행)을 실행하고 관심있는 각 서비스에 대한 브라우저를 추가합니다 (27,28 행). 이것은 원칙적으로 작동합니다.파이썬 미스 서비스로 avahi 서비스 찾아보기

내 문제는 내가 항상 모든 서비스를받지 못한다는 것입니다. 때로는 사용할 수있는 모든 서비스가 나열되고 때로는 일부 서비스가 나열되지 않을 수도 있습니다. 내 생각 엔 적절한 신호가 연결되기 전에 브라우저가 서비스를 반복하기 시작합니다 (라인 41-44). 그러나이를 해결할 방법이 없습니다. 실패를 보여주는 최소한의 예 아래에.

인터넷에서 본 대부분의 예 (예 : Stopping the Avahi service and return a list of elements)는 브라우저를 설정하고 신호를 연결 한 후 MainLoop을 실행합니다. "AllForNow"신호가 수신되면 루프가 종료됩니다. 브라우저가 계속 실행되고 새롭거나 제거 된 서비스를 청취해야하므로 (나에게 신뢰할 수있는 방식으로 작동하며 초기 쿼리에는 문제가 있음) 나를위한 옵션이 아닙니다.

#!/usr/bin/python 
import dbus 
from dbus.mainloop.glib import DBusGMainLoop 
import avahi 
import gobject 
import threading 

gobject.threads_init() 
dbus.mainloop.glib.threads_init() 

class ZeroconfBrowser: 
    def __init__(self): 
     self.service_browsers = set() 
     self.services = {} 
     self.lock = threading.Lock() 

     loop = DBusGMainLoop(set_as_default=True) 
     self._bus = dbus.SystemBus(mainloop=loop) 
     self.server = dbus.Interface(
       self._bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), 
       avahi.DBUS_INTERFACE_SERVER) 

     thread = threading.Thread(target=gobject.MainLoop().run) 
     thread.daemon = True 
     thread.start() 

     self.browse("_ssh._tcp") 
     self.browse("_http._tcp") 

    def browse(self, service): 
     if service in self.service_browsers: 
      return 
     self.service_browsers.add(service) 

     with self.lock: 
      browser = dbus.Interface(self._bus.get_object(avahi.DBUS_NAME, 
        self.server.ServiceBrowserNew(avahi.IF_UNSPEC, 
          avahi.PROTO_UNSPEC, service, 'local', dbus.UInt32(0))), 
        avahi.DBUS_INTERFACE_SERVICE_BROWSER) 

      browser.connect_to_signal("ItemNew", self.item_new) 
      browser.connect_to_signal("ItemRemove", self.item_remove) 
      browser.connect_to_signal("AllForNow", self.all_for_now) 
      browser.connect_to_signal("Failure", self.failure) 

    def resolved(self, interface, protocol, name, service, domain, host, 
      aprotocol, address, port, txt, flags): 
     print "resolved", interface, protocol, name, service, domain, flags 

    def failure(self, exception): 
     print "Browse error:", exception 

    def item_new(self, interface, protocol, name, stype, domain, flags): 
     with self.lock: 
      self.server.ResolveService(interface, protocol, name, stype, 
        domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), 
        reply_handler=self.resolved, error_handler=self.resolve_error) 

    def item_remove(self, interface, protocol, name, service, domain, flags): 
     print "removed", interface, protocol, name, service, domain, flags 

    def all_for_now(self): 
     print "all for now" 

    def resolve_error(self, *args, **kwargs): 
     with self.lock: 
      print "Resolve error:", args, kwargs 

import time 
def main(): 
    browser = ZeroconfBrowser() 
    while True: 
     time.sleep(3) 
     for key, value in browser.services.items(): 
      print key, str(value) 

if __name__ == '__main__': 
    main() 

답변

0

설치 가능한 python-dbus 패키지를 찾을 수 없습니다. 그러나 나는 위대한 작품을 예를 Avahi 브라우저 찾았어요 - avahi.py

pip install python-tdbus 

소스를

#!/usr/bin/env python 
# 
# This file is part of python-tdbus. Python-tdbus is free software 
# available under the terms of the MIT license. See the file "LICENSE" that 
# was provided together with this source file for the licensing terms. 
# 
# Copyright (c) 2012 the python-tdbus authors. See the file "AUTHORS" for a 
# complete list. 

# This example shows how to access Avahi on the D-BUS. 


from tdbus import SimpleDBusConnection, DBUS_BUS_SYSTEM, DBusHandler, signal_handler, DBusError 

import logging 

logging.basicConfig(level=logging.DEBUG) 

CONN_AVAHI = 'org.freedesktop.Avahi' 
PATH_SERVER = '/' 
IFACE_SERVER = 'org.freedesktop.Avahi.Server' 

conn = SimpleDBusConnection(DBUS_BUS_SYSTEM) 

try: 
    result = conn.call_method(PATH_SERVER, 'GetVersionString', 
         interface=IFACE_SERVER, destination=CONN_AVAHI) 
except DBusError: 
    print 'Avahi NOT available.' 
    raise 

print 'Avahi is available at %s' % CONN_AVAHI 
print 'Avahi version: %s' % result.get_args()[0] 
print 
print 'Browsing service types on domain: local' 
print 'Press CTRL-c to exit' 
print 

result = conn.call_method('/', 'ServiceTypeBrowserNew', interface=IFACE_SERVER, 
        destination=CONN_AVAHI, format='iisu', args=(-1, 0, 'local', 0)) 
browser = result.get_args()[0] 
print browser 
class AvahiHandler(DBusHandler): 

    @signal_handler() 
    def ItemNew(self, message): 
    args = message.get_args() 
     print 'service %s exists on domain %s' % (args[2], args[3]) 

conn.add_handler(AvahiHandler()) 
conn.dispatch() 

출력

Avahi is available at org.freedesktop.Avahi 
Avahi version: avahi 0.6.31 

Browsing service types on domain: local 
Press CTRL-c to exit 

/Client1/ServiceTypeBrowser1 
service _udisks-ssh._tcp exists on domain local 
service _workstation._tcp exists on domain local 
service _workstation._tcp exists on domain local 
service _udisks-ssh._tcp exists on domain local 
관련 문제