write DBUS Services (I)

空扰寡人 提交于 2019-12-06 08:39:22

Those days I had to make a D-Bus server and client in python and I thought to share with you guys some things about the D-Bus.

First of all, what is D-Bus? Well, D-Bus is a system that offers a communication channel for multiple programs.

Someone must also distinguish between: session and system bus.

The session bus is specific for each user, while the system bus is specially designed for the state of the whole system and can change this state (like adding a new storage device, the internet connection suffers some modification).

“Talk is cheap, show me the code”  Linus Torvalds

One example of a session bus server is the following

#!/usr/bin/env python3

from gi.repository import GLib
import dbus
import dbus.service

from dbus.mainloop.glib import DBusGMainLoop

class Session_DBus(dbus.service.Object):
    def __init__(self):
        bus_name=dbus.service.BusName('org.me.test_session',bus=dbus.SessionBus())
        dbus.service.Object.__init__(self,bus_name,'/org/me/test_session')

    @dbus.service.method('org.me.test1')
    def session_bus_message1(sefl):
        return "Session Bus 1"

    @dbus.service.method('org.me.test2')
    def session_bus_message2(self):
        return "Session Bus 2"

    @dbus.service.method('org.me.test2')
    def session_bus_strings(self,string1,string2):
        return string1+" "+string2



DBusGMainLoop(set_as_default=True)
dbus_service=Session_DBus()

try:
    GLib.MainLoop().run()
except KeyboardInterrupt:
    print("\nThe MainLoop will close...")
    GLib.MainLoop().quit()

And the client (2 versions):

Version 1:

#!/usr/bin/env python3

import dbus
bus = dbus.SessionBus()
session = bus.get_object("org.me.test_session", "/org/me/test_session")

method_message1 = session.get_dbus_method('session_bus_message1', 'org.me.test1')
method_message2 = session.get_dbus_method('session_bus_message2', 'org.me.test2')
method_message3 = session.get_dbus_method('session_bus_strings', 'org.me.test2')

print(method_message1())
#interface1 = dbus.Interface(session, "org.me.test1")
#print(interface1.session_bus_message1())
print(method_message2())
print(method_message3("Hello", "World"))

Version 2:

#!/usr/bin/env python3

import dbus
bus = dbus.SessionBus()
session = bus.get_object("org.me.test_session", "/org/me/test_session")
interface1 = dbus.Interface(session, "org.me.test1")
interface2 = dbus.Interface(session, "org.me.test2")

print(interface1.session_bus_message1())
print(interface2.session_bus_message2())
print(interface2.session_bus_strings("hello", "world"))

For the client scripts to run, one must first run the script for the server and after that to run theclients. Also if you want to have to have the server initiated (to not manually run it) you could create a file with a .service extension  in/usr/share/dbus-1/service/; let’s say my-test-session.service with the following content:

[D-BUS Service]
Name=org.me.test_session
Exec="/home/charles/my-test-session.py"

After this you can run only the clients and the system would know where server part is and how to handle it. Also, do not forget to make the server scriptexecutable.


we can verify this service using dbus tools:

$ dbus-send --session --type=method_call --print-reply --dest="org.me.test_session" /org/me/test_session org.freedesktop.DBus.Introspectable.Introspect
method return time=1491700435.911482 sender=:1.133 -> destination=:1.134 serial=3 reply_serial=2
   string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/org/me/test_session">
  <interface name="org.freedesktop.DBus.Introspectable">
    <method name="Introspect">
      <arg direction="out" type="s" />
    </method>
  </interface>
  <interface name="org.me.test1">
    <method name="session_bus_message1">
    </method>
  </interface>
  <interface name="org.me.test2">
    <method name="session_bus_message2">
    </method>
    <method name="session_bus_strings">
      <arg direction="in"  type="v" name="string1" />
      <arg direction="in"  type="v" name="string2" />
    </method>
  </interface>
</node>
"

dbus-send --session --type=method_call --print-reply --dest="org.me.test_session" /org/me/test_session org.me.test2.session_bus_strings string:"hello" string:"world"
method return time=1491700611.464318 sender=:1.133 -> destination=:1.137 serial=4 reply_serial=2
   string "hello world"

https://georgemuraruc.wordpress.com/2015/07/16/d-bus-tutorial-for-python/


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!