Re: GDBusProxy missing bus signals during construction



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]