xpra icon
Bug tracker and wiki

Opened 7 years ago

Closed 7 years ago

#450 closed task (fixed)

forwarding dbus objects - generalized

Reported by: Antoine Martin Owned by: alas
Priority: minor Milestone: 0.11
Component: core Version:
Keywords: dbus Cc:

Description (last modified by Antoine Martin)

Originally recorded as #22 (more dbus quircks in #83)

It would be nice to expose server-side dbus objects to the client.
Not just notifications as done in #22. So client-side applications could interact with server-side applications through the link we already have.

Based on dbus-python examples - which we should be able to forward easily enough:

  • we should be able to get notified when a specific service becomes available, as dbus-monitor already shows:
    signal sender=org.freedesktop.DBus -> dest=(null destination) serial=690 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged
    
  • then we can introspect it
    method call sender=:1.413 -> dest=org.freedesktop.DBus serial=1 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=Hello
    signal sender=org.freedesktop.DBus -> dest=(null destination) serial=691 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged
       string "com.example.SampleService"
    
  • forward this to the client via a new packet-type (and client feature) - "add-service"?
  • the client can then create the corresponding service dynamically (and add a prefix if desired / configured to do so)
  • when an application calls the client's new dbus service, we have to forward the call to the server ("call-service"?) and return only once we get the result ("service-return"?) - probably re-using the nested mainloop code since the bindings will share the same main loop

For clients that do not have dbus support (OSX, win32 or posix clients without a dbus session running), we can still provide ways of interacting with the remote dbus session:

  • programmatically in the client
  • via "--key-shortcut=SHORTCUT:service_call(xyz)"
  • exposing some of those services via the tray or via a custom window layout

For services we cannot introspect... nothing for now.

Since there is nothing that requires us to be tied to dbus, we should ensure that other RPC tools can be plugged in without too much effort - (whilst still targetting dbus as the main RPC implementation)

Attachments (2)

dbus-listener.py (787 bytes) - added by Antoine Martin 7 years ago.
example dbus service which can be used for testing
dbus-sender.py (220 bytes) - added by Antoine Martin 7 years ago.
example client for the example service

Download all attachments as: .zip

Change History (9)

comment:1 Changed 7 years ago by Antoine Martin

Description: modified (diff)
Keywords: dbus added
Owner: changed from Antoine Martin to Antoine Martin
Status: newassigned

comment:2 Changed 7 years ago by Antoine Martin

Description: modified (diff)

comment:3 Changed 7 years ago by Antoine Martin

Description: modified (diff)
Summary: forwarding dbus objectsforwarding dbus objects - generalized

comment:4 Changed 7 years ago by Antoine Martin

More pointers:

The first problem is that although dbus defines an introspection interface, the output is in XML (PITA!). And we don't want to know about the interface we export in advance. Yuk, even dbus-inspector is parsing XML...

Another, bigger problem is that dbus calls expect to return immediately, and will block the main loop until we do return... which will never return if we deadlock trying to use the network from the mainloop (more info here). Using the nested main loop code is off-putting, and would not work on osx. Using our own dedicated dbus thread for the main loop could work, but would not play well with any other dbus calls we could end up making... (ie: notifications)

Also, I can't see how we would dynamically add the methods we found through introspection to an object we register. The service method are normally registered using annotations..

Finally, the gtk all-in-one we use on win32 does not include dbus...
Although building dbus python on windows is documented, that's unlikely to be easy to manage... Maybe we can use an equivalent for windows.

Last edited 7 years ago by Antoine Martin (previous) (diff)

Changed 7 years ago by Antoine Martin

Attachment: dbus-listener.py added

example dbus service which can be used for testing

Changed 7 years ago by Antoine Martin

Attachment: dbus-sender.py added

example client for the example service

comment:5 Changed 7 years ago by Antoine Martin

Owner: changed from Antoine Martin to alas
Status: assignednew

As of r4759, we can call server-side dbus services and get the reply asynchronously:

  • programmatically: see dbus_call in xpra.client.ui_client_base.py
  • via keyboard shortcuts (the response is ignored - only strings, numbers and None are recognized as arguments)


The number of arguments to the service's function is variable and optional. You can specify as many or as few as you like, and the type of the arguments will be preserved over the wire.



Attached is an example dbus service (and an example client - just for completeness, not used), start it from within an xpra session which has a dbus server, then you can interact with it from the client end:

  • programmatically:
    client.dbus_call('org.xpra.Test', '/org/xpra/Test', 'org.xpra.Test', 'Notify', None, None, 'themessage')
    
  • using the key shortcut Meta+Shift+F7:
    xpra attach :10 "--key-shortcut=Meta+Shift+F7:dbus_call('org.xpra.Test', \
        '/org/xpra/Test', 'org.xpra.Test', 'Notify', None, None, 'hello')"
    

Then you just trigger the dbus call using the key combination.


To enable the dbus server-side debugging, set:

XPRA_DBUS_DEBUG=1 xpra start ...

Probably complete enough for a first round of feedback.

Last edited 7 years ago by Antoine Martin (previous) (diff)

comment:6 Changed 7 years ago by alas

It took some hand-holding from Smo to get the python dbus-listener.py in place on the server, but once that was done the Notify message came through clear as... day.

If you need me to run the debugger to get some output (because I'm sure you need the reading) let me know, but since it seemed to work exactly as hoped with a fedora 19 client and server, I suspect that won't be necessary.

comment:7 Changed 7 years ago by Antoine Martin

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.