2010-08-07 10 views
15

Ich versuche, eine Client/Server-Lösung mit Python zu entwickeln, der Server muss die Service-Verfügbarkeit mit Avahi Broadcast. Ich bin mit dem folgenden Code, den Dienst zu veröffentlichen:Wie entwickle ich einen Avahi Client/Server

import avahi 
import dbus 

__all__ = ["ZeroconfService"] 

class ZeroconfService: 
    """A simple class to publish a network service with zeroconf using 
    avahi. 

    """ 

    def __init__(self, name, port, stype="_http._tcp", 
       domain="", host="", text=""): 
     self.name = name 
     self.stype = stype 
     self.domain = domain 
     self.host = host 
     self.port = port 
     self.text = text 

    def publish(self): 
     bus = dbus.SystemBus() 
     server = dbus.Interface(
         bus.get_object(
           avahi.DBUS_NAME, 
           avahi.DBUS_PATH_SERVER), 
         avahi.DBUS_INTERFACE_SERVER) 

     g = dbus.Interface(
        bus.get_object(avahi.DBUS_NAME, 
            server.EntryGroupNew()), 
        avahi.DBUS_INTERFACE_ENTRY_GROUP) 

     g.AddService(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC,dbus.UInt32(0), 
        self.name, self.stype, self.domain, self.host, 
        dbus.UInt16(self.port), self.text) 

     g.Commit() 
     self.group = g 

    def unpublish(self): 
     self.group.Reset() 


def test(): 
    service = ZeroconfService(name="TestService", port=3000) 
    service.publish() 
    raw_input("Press any key to unpublish the service ") 
    service.unpublish() 


if __name__ == "__main__": 
    test() 

Wie für die Kunden, ich versuche, für den Dienst suchen mit:

# http://avahi.org/wiki/PythonBrowseExample 
import dbus, gobject, avahi 
from dbus import DBusException 
from dbus.mainloop.glib import DBusGMainLoop 

# Looks for iTunes shares 

TYPE = "_http._tcp" 

def service_resolved(*args): 
    print 'service resolved' 
    print 'name:', args[2] 
    print 'address:', args[7] 
    print 'port:', args[8] 

def print_error(*args): 
    print 'error_handler' 
    print args[0] 

def myhandler(interface, protocol, name, stype, domain, flags): 
    print "Found service '%s' type '%s' domain '%s' " % (name, stype, domain) 

    if flags & avahi.LOOKUP_RESULT_LOCAL: 
      # local service, skip 
      pass 

    server.ResolveService(interface, protocol, name, stype, 
     domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), 
     reply_handler=service_resolved, error_handler=print_error) 

loop = DBusGMainLoop() 

bus = dbus.SystemBus(mainloop=loop) 

server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, '/'), 
     'org.freedesktop.Avahi.Server') 

sbrowser = dbus.Interface(bus.get_object(avahi.DBUS_NAME, 
     server.ServiceBrowserNew(avahi.IF_UNSPEC, 
      avahi.PROTO_UNSPEC, TYPE, 'local', dbus.UInt32(0))), 
     avahi.DBUS_INTERFACE_SERVICE_BROWSER) 

sbrowser.connect_to_signal("ItemNew", myhandler) 

gobject.MainLoop().run() 

jedoch der Client erkennt nicht, wenn der Dienst ist gestartet. Irgendwelche Ideen, was ich falsch mache?

Antwort

2

Ich habe festgestellt, dass der Code wie erwartet funktioniert. Ich hatte Firewall-Regeln, die das Avahi-Publishing blockierten.

+0

Dies funktioniert gut, ich habe Ihren ausgezeichneten Code wieder verwendet. Aber mit dem neuesten Fedora (und vielleicht anderen), bekomme ich: 'dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownMethod: Methode "AddService" mit Signatur "iiusssqs" auf der Schnittstelle "org.freedesktop.Avahi .EntryGroup "existiert nicht" – totaam

+1

Weitere Details und das Update finden Sie hier: http://xpra.org/trac/ticket/1153 Sie müssen jetzt "avahi.string_array_to_txt_array" in den TXT-Datensätzen aufrufen. – totaam