2010-08-07 12 views
15

Sto provando a sviluppare una soluzione client/server utilizzando python, il server deve trasmettere la disponibilità del servizio utilizzando Avahi. Sto usando il seguente codice per pubblicare il servizio:Come sviluppare un client/server 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() 

Per quanto riguarda il cliente, che sto cercando di cercare il servizio con:

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

Tuttavia il cliente non rileva quando il servizio è iniziato. Qualche idea su cosa sto facendo male?

risposta

2

Ho trovato che il codice funziona come previsto. Avevo regole firewall che bloccavano la pubblicazione relativa avahi.

+0

Questo ha funzionato correttamente, ho riutilizzato il codice eccellente. Ma con l'ultimo Fedora (e forse altri), ottengo: 'dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownMethod: Metodo "AddService" con firma "iiussssqs" sull'interfaccia "org.freedesktop.Avahi .EntryGroup "inesistente" – totaam

+1

Ulteriori dettagli e la correzione possono essere trovati qui: http://xpra.org/trac/ticket/1153 Devi chiamare "avahi.string_array_to_txt_array" nei record TXT ora. – totaam