2010-08-07 7 views
15

J'essaie de développer une solution client/serveur en utilisant python, le serveur doit diffuser la disponibilité du service en utilisant Avahi. J'utilise le code suivant pour publier le service:Comment développer un client/serveur Avahi

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() 

En ce qui concerne le client, je suis en train de rechercher le service avec:

# 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() 

Toutefois, le client ne détecte pas lorsque le service a démarré. Des idées sur ce que je fais mal?

Répondre

2

J'ai trouvé que le code fonctionne comme prévu. J'avais des règles de pare-feu bloquant la publication liée d'avahi.

+0

Cela a l'habitude de bien fonctionner, j'ai réutilisé votre excellent code. Mais avec la dernière Fedora (et peut-être d'autres), je reçois: 'dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownMethod: Méthode "AddService" avec la signature "iiussssqs" sur l'interface "org.freedesktop.Avahi .EntryGroup "n'existe pas" – totaam

+1

Plus de détails et le correctif peuvent être trouvés ici: http://xpra.org/trac/ticket/1153 Vous devez appeler 'avahi.string_array_to_txt_array' sur les enregistrements TXT maintenant. – totaam