현재 사용할 수있는 특정 유형의 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()