Re: GDBusProxy missing bus signals during construction
- From: Andrejs Hanins <andrejs hanins ubnt com>
- To: gtk-devel-list gnome org
- Subject: Re: GDBusProxy missing bus signals during construction
- Date: Thu, 23 Jul 2015 19:09:00 +0300
Hi,
On 07/23/2015 05:01 PM, Roger James wrote:
I am trying to implement a Zeroconf service browser using a PyGobject Gio.DBusProxy object to talk to
avahi. It all works fine but the browser randomly misses the initial one or more ItemNew signals from the
avahi server. It sometimes even misses the AllForNow signal. Subsequent ItemNew signals are seen OK as
services come and go.
It appears that the problem is that the GLIb objects subscribes to the dbus signals during the construction
process (the DO_NOT_CONNECT_SIGNALS is not set). It then notifies(GDbusProxy.new) or
returns(GDBusProxy.new_sync) to the calling object. Once I get the new proxy object back I can use connect
on the parent gobject to hook the incoming dbus signal to my applications signal handling callback. However
any dbus signals that arrive from server (avahi) before that connection is made are discarded. If set
DO_NOT_CONNECT_SIGNALS I would have mimic the whole of DBusProxy/DBUsConection's handling of dbus side
signal mapping. I don't want to have to do that. What am I missing?
Some fundamental questions are.
1. How can I stop this happening.
2. Is avahi breaking some sort of dbus protocol or convention in sending these signals immediately a new
bus connection is made?
3. Is the a flaw in the GDBusProxy design/documenation? (sorry guys, but have spent a while looing at this.)
I had a very similar problem using native GDbus/Glibmm and the only solution which helped me was to subscribe
to signals *in advance*, i.e. before the proxy object is created. I would also be happy to know a better way.
Thanks,
Roger
Here is my python code
#!/usr/bin/env python
from gi.repository import Gio, GLib, GObject, Gtk
import avahi
import signal
import time
class avahibrowser(Gio.Application):
def service_resolved(self, *args):
print 'service resolved'
print 'name:', args[2]
print 'address:', args[7]
print 'port:', args[8]
def print_error(self, *args):
print 'error_handler'
print args[0]
def browserCallback(self, proxy, sender, signal, args):
if signal == 'ItemNew':
# Arguments are [0] i interface, [1] i protocol [2] s name [3] s type [4] s domain [5] u flags
print "Found service '%s' type '%s' domain '%s' " % (args[2], args[3], args[4])
#self.avahiserver.ResolveService('iisssiu',
# args[0], # Interface
# args[1], # Protocol
# args[2], # Name
# args[3], # Service Type
# args[4], # Domain
# avahi.PROTO_UNSPEC, dbus.UInt32(0),
# reply_handler=self.service_resolved, error_handler=self.print_error)
else:
print 'signal', signal, 'arguments', args
def do_activate(self): # Define this to suppress glib warning
pass
def new_browser_proxy_callback(self, source_object, res, user_data):
#source_object.connect('g-signal', self.browserCallback)
self.avahibrowser = Gio.DBusProxy.new_finish(res)
self.avahibrowser.connect('g-signal', self.browserCallback)
def new_server_proxy_callback(self, source_object, res, user_data):
self.avahiserver = Gio.DBusProxy.new_finish(res)
avahibrowserpath = self.avahiserver.ServiceBrowserNew('(iissu)',
avahi.IF_UNSPEC,
avahi.PROTO_INET,
'_scratch._tcp',
'local',
0)
Gio.DBusProxy.new(self.systemDBusConnection, 0, None,
avahi.DBUS_NAME,
avahibrowserpath,
avahi.DBUS_INTERFACE_SERVICE_BROWSER, None,
self.new_browser_proxy_callback, None)
def bus_get_callback(self, source_object, res, user_data):
self.systemDBusConnection = Gio.bus_get_finish(res)
Gio.DBusProxy.new(self.systemDBusConnection, 0, None,
avahi.DBUS_NAME,
avahi.DBUS_PATH_SERVER,
avahi.DBUS_INTERFACE_SERVER, None,
self.new_server_proxy_callback, None)
# Gnome application initialization routine
def __init__(self, application_id, flags):
Gio.Application.__init__(self, application_id=application_id, flags=flags)
Gio.bus_get(Gio.BusType.SYSTEM, None, self.bus_get_callback, None)
def InitSignal(app):
def signal_action(signal):
if signal is 1:
print("Caught signal SIGHUP(1)")
elif signal is 2:
print("Caught signal SIGINT(2)")
elif signal is 15:
print("Caught signal SIGTERM(15)")
app.release()
def idle_handler(*args):
print("Python signal handler activated.")
GLib.idle_add(signal_action, priority=GLib.PRIORITY_HIGH)
def handler(*args):
print("GLib signal handler activated.")
signal_action(args[0])
def install_glib_handler(sig):
unix_signal_add = None
if hasattr(GLib, "unix_signal_add"):
unix_signal_add = GLib.unix_signal_add
elif hasattr(GLib, "unix_signal_add_full"):
unix_signal_add = GLib.unix_signal_add_full
if unix_signal_add:
print("Register GLib signal handler: %r" % sig)
unix_signal_add(GLib.PRIORITY_HIGH, sig, handler, sig)
else:
print("Can't install GLib signal handler, too old gi.")
SIGS = [getattr(signal, s, None) for s in "SIGINT SIGTERM SIGHUP".split()]
for sig in filter(None, SIGS):
print("Register Python signal handler: %r" % sig)
signal.signal(sig, idle_handler)
GLib.idle_add(install_glib_handler, sig, priority=GLib.PRIORITY_HIGH)
if __name__ == "__main__":
Application = avahibrowser("uk.co.beardandsandals.avahibrowser", Gio.ApplicationFlags.FLAGS_NONE)
# Set up python and Gio signal handling
InitSignal(Application)
Application.hold()
Application.run(None)
print 'Exiting'
_______________________________________________
gtk-devel-list mailing list
gtk-devel-list gnome org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]