Author: dmeyer
Date: Wed Mar 5 16:35:41 2008
New Revision: 3163
Log:
- Support more than one service to be provided.
- Add removal of a service
Known Bug: changing of TXT records of a service does not
work, I have no idea how to detect that on client side.
Modified:
trunk/base/src/net/mdns.py
trunk/base/test/mdns.py
Modified: trunk/base/src/net/mdns.py
==============================================================================
--- trunk/base/src/net/mdns.py (original)
+++ trunk/base/src/net/mdns.py Wed Mar 5 16:35:41 2008
@@ -9,6 +9,10 @@
# mdns implementations are not supported yet but should be added later to
# support other platforms like OSX.
#
+# TODO: Update service txt record. There is a function UpdateServiceTxt and
+# it looks like it does something, but the service browser does not have a
+# signal to detect this.
+#
# -----------------------------------------------------------------------------
# Copyright (C) 2008 Dirk Meyer
#
@@ -99,12 +103,18 @@
self._bus = None
self._services = {}
self._announce = None
-
+ self._provided = {}
+ self._nextid = 0
+ self._sync_running = False
+ self._sync_required = False
+
@kaa.threaded(kaa.GOBJECT)
def provide(self, name, type, port, txt):
"""
Provide a service with the given name and type listening on the given
- port with additional information in the txt record.
+ port with additional information in the txt record. This function
returns
+ an InProgress object with the id of the service to remove the service
+ later.
"""
if self._bus is None:
self._dbus_connect()
@@ -112,7 +122,8 @@
self._announce = dbus.Interface(
self._bus.get_object( avahi.DBUS_NAME,
self._avahi.EntryGroupNew()),
avahi.DBUS_INTERFACE_ENTRY_GROUP)
- self._announce.AddService(
+ self._nextid += 1
+ self._provided[self._nextid] = [
avahi.IF_UNSPEC, # interface
avahi.PROTO_UNSPEC, # protocol
0, # flags
@@ -120,9 +131,56 @@
"", # domain
"", # host
dbus.UInt16(port), # port
- avahi.string_array_to_txt_array([ '%s=%s' % t for t in txt.items()
]))
- self._announce.Commit()
+ avahi.string_array_to_txt_array([ '%s=%s' % t for t in txt.items()
]),
+ ]
+ self._sync_required = True
+ self._sync()
+ return self._nextid
+ @kaa.threaded(kaa.GOBJECT)
+ def remove(self, id):
+ """
+ Remove a service.
+ """
+ if id in self._provided:
+ self._provided.pop(id)
+ self._sync_required = True
+ self._sync()
+
+ def _sync(self):
+ """
+ Sync providing service list to avahi. This is an internal function that
+ has to be called from a function running in the GOBJECT thread.
+ """
+ # return if nothing to do
+ if self._sync_running or not self._sync_required:
+ return
+ # dbus callbacks to block sync
+ callbacks = dict(
+ reply_handler=self._sync_finished,
+ error_handler=self._sync_finished
+ )
+ self._sync_running = True
+ self._sync_required = False
+ if not self._provided:
+ self._announce.Reset(**callbacks)
+ return
+ self._announce.Reset()
+ for service in self._provided.values():
+ self._announce.AddService(*service)
+ self._announce.Commit(**callbacks)
+
+ def _sync_finished(self, error=None):
+ """
+ Dbus event when sync is finished. This is an internal function that
+ has to be called from a function running in the GOBJECT thread.
+ """
+ if error:
+ # something went wrong
+ log.error(error)
+ self._sync_running = False
+ self._sync()
+
def get_type(self, service):
"""
Get a ServiceList object for the given type.
@@ -142,7 +200,7 @@
self._avahi = dbus.Interface(
self._bus.get_object( avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER ),
avahi.DBUS_INTERFACE_SERVER )
-
+
@kaa.threaded(kaa.GOBJECT)
def _service_add_browser(self, service):
"""
@@ -162,7 +220,7 @@
avahi.DBUS_INTERFACE_SERVICE_BROWSER)
browser.connect_to_signal('ItemNew', self._service_new)
browser.connect_to_signal('ItemRemove', self._service_remove)
-
+
@kaa.threaded(kaa.MAINTHREAD)
def _service_remove(self, interface, protocol, name, type, domain, flags):
"""
@@ -213,3 +271,4 @@
# create functions to use from the outside
provide = mdns.provide
get_type = mdns.get_type
+remove = mdns.remove
Modified: trunk/base/test/mdns.py
==============================================================================
--- trunk/base/test/mdns.py (original)
+++ trunk/base/test/mdns.py Wed Mar 5 16:35:41 2008
@@ -18,10 +18,14 @@
def removed(service):
print 'lost', service
+def provide_callback(id, sec):
+ kaa.OneShotTimer(mdns.remove, id).start(sec)
+
if len(sys.argv) > 1:
# go into provide mode
# mdns.py ServiceName Port
- mdns.provide(sys.argv[1], '_test._tcp', int(sys.argv[2]), {'foo': 'bar'})
+ mdns.provide(sys.argv[1], '_test._tcp', int(sys.argv[2]), {'foo':
'bar'}).connect(provide_callback, 2)
+ mdns.provide(sys.argv[1] + 'x', '_test._tcp', int(sys.argv[2]), {'foo':
'bar'}).connect(provide_callback, 5)
else:
# go into listen mode
# monitor printer
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog