2010-08-07 53 views
15

我正在尝试使用python开发客户端/服务器解决方案,服务器必须使用Avahi广播服务可用性。我使用下面的代码来发布服务:如何开发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() 

至于客户端,我想搜索与服务:

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

但是客户端没有检测当服务开始。关于我做错什么的想法?

回答

2

我发现代码正常工作。我有阻止avahi相关发布的防火墙规则。

+0

这用于正常工作,我已经重新使用您的优秀代码。 但是使用最新的Fedora(也可能是其他的),我得到: 'dbus.exceptions.DBusException:org.freedesktop.DBus.Error.UnknownMethod:方法“AddService”在接口“org.freedesktop.Avahi”上签名为“iiussssqs” .EntryGroup“不存在” – totaam 2016-03-27 04:39:43

+1

更多详细信息和解决办法可以在这里找到:http://xpra.org/trac/ticket/1153 你现在必须在TXT记录上调用'avahi.string_array_to_txt_array'。 – totaam 2016-03-27 05:38:02