2010-08-07 16 views
15

Próbuję opracować rozwiązanie klient/serwer przy użyciu Pythona, serwer musi rozgłaszać dostępność usługi za pomocą Avahi. Używam następujący kod do publikowania usługę:Jak opracować klienta/serwer 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() 

Jak dla klienta, próbuję wyszukać usługi z:

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

Jednak klient nie wykrywa, gdy usługa jest uruchomiony. Jakieś pomysły na temat tego, co robię źle?

Odpowiedz

2

Znalazłem, że kod działa zgodnie z oczekiwaniami. Miałem reguły firewalla blokujące publikowanie związane z avahi.

+0

To działało dobrze, ponownie użyłem twojego doskonałego kodu. Ale z najnowszą Fedorą (i może innymi) otrzymuję: "dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UNknownMethod: Metoda" AddService "z podpisem" iiussssqs "w interfejsie" org.freedesktop.Avahi .EntryGroup "nie istnieje" – totaam

+1

Więcej szczegółów i poprawkę można znaleźć tutaj: http://xpra.org/trac/ticket/1153 Musisz teraz wywołać "avahi.string_array_to_txt_array" na rekordach TXT. – totaam

Powiązane problemy