linux 进程间通信 dbus-glib实例详解二(下) 消息和消息总线(ListActivatableNames和服务器的自动启动)(附代码)

Posted Dontla

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 进程间通信 dbus-glib实例详解二(下) 消息和消息总线(ListActivatableNames和服务器的自动启动)(附代码)相关的知识,希望对你有一定的参考价值。

linux 进程间通信 dbus-glib【实例】详解一(附代码)(d-feet工具使用)

linux 进程间通信 dbus-glib【实例】详解二(上) 消息和消息总线(附代码)

linux 进程间通信 dbus-glib【实例】详解二(下) 消息和消息总线(ListActivatableNames和服务器的自动启动)(附代码)

文章目录

dbus实例讲解(二下):消息和消息总线

2.3.2、ListActivatableNames和服务器的自动启动

运行:(普通用户下都能运行,root用户下只能运行system,session运行不了)

$ dbus-send --system --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListActivatableNames

$ dbus-send --session --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListActivatableNames
返回的数据是一样的。在我的电脑上返回的数据是:

   array [
      string "org.freedesktop.DBus"
      string "org.freedesktop.Notifications"
      string "net.ekiga.helper"
      string "org.freedesktop.PowerManagement"
      string "org.freedesktop.Tracker"
      string "org.freedesktop.SystemToolsBackends.GroupsConfig"
      string "org.freedesktop.SystemToolsBackends.NTPConfig"
      string "org.gnome.Tomboy"
      string "org.freedesktop.SystemToolsBackends.HostsConfig"
      string "org.freedesktop.SystemToolsBackends.NFSConfig"
      string "org.freedesktop.SystemToolsBackends"
      string "net.ekiga.instance"
      string "org.gnome.GnomeVFS.Daemon"
      string "com.redhat.dhcp"
      string "org.freedesktop.SystemToolsBackends.TimeConfig"
      string "org.freedesktop.SystemToolsBackends.IfacesConfig"
      string "org.freedesktop.SystemToolsBackends.ServicesConfig"
      string "org.gnome.Rhythmbox"
      string "org.freedesktop.SystemToolsBackends.Platform"
      string "org.freedesktop.SystemToolsBackends.UsersConfig"
      string "org.freedesktop.SystemToolsBackends.SMBConfig"
      string "org.gnome.SettingsDaemon"
   ]

我们也可以用python脚本调用ListActivatableNames。例如:写一个叫dls.py的脚本:(我ubuntu没装python就不演示了)

$ cat dls.py
#!/usr/bin/env python
import dbus
bus=dbus.SystemBus()
bus_obj=bus.get_object('org.freedesktop.DBus', '/')
iface=dbus.Interface(bus_obj, 'org.freedesktop.DBus')
names=iface.ListActivatableNames()
for n in names:
    print n

运行:

$ ./dls.py |sort

输出为:

com.redhat.dhcp
net.ekiga.helper
net.ekiga.instance
org.freedesktop.DBus
org.freedesktop.Notifications
org.freedesktop.PowerManagement
org.freedesktop.SystemToolsBackends
org.freedesktop.SystemToolsBackends.GroupsConfig
org.freedesktop.SystemToolsBackends.HostsConfig
org.freedesktop.SystemToolsBackends.IfacesConfig
org.freedesktop.SystemToolsBackends.NFSConfig
org.freedesktop.SystemToolsBackends.NTPConfig
org.freedesktop.SystemToolsBackends.Platform
org.freedesktop.SystemToolsBackends.ServicesConfig
org.freedesktop.SystemToolsBackends.SMBConfig
org.freedesktop.SystemToolsBackends.TimeConfig
org.freedesktop.SystemToolsBackends.UsersConfig
org.freedesktop.Tracker
org.gnome.GnomeVFS.Daemon
org.gnome.Rhythmbox
org.gnome.SettingsDaemon
org.gnome.Tomboy

使用python脚本调用dbus接口是不是很简单。如果你看过dbus-glib的代码(后面会讲解),你对python的简洁会有更深刻的感触(额,,,这是暗示dbus-glib代码很复杂??)。如果你执行:

$ cat /usr/share/dbus-1/services/*|grep Name|awk -F= 'print $2'|sort

(ubuntu里service里有东西,arm摄像头service目录下啥也没有)
你会得到:

com.redhat.dhcp
net.ekiga.helper
net.ekiga.instance
org.freedesktop.Notifications
org.freedesktop.PowerManagement
org.freedesktop.SystemToolsBackends
org.freedesktop.SystemToolsBackends.GroupsConfig
org.freedesktop.SystemToolsBackends.HostsConfig
org.freedesktop.SystemToolsBackends.IfacesConfig
org.freedesktop.SystemToolsBackends.NFSConfig
org.freedesktop.SystemToolsBackends.NTPConfig
org.freedesktop.SystemToolsBackends.Platform
org.freedesktop.SystemToolsBackends.ServicesConfig
org.freedesktop.SystemToolsBackends.SMBConfig
org.freedesktop.SystemToolsBackends.TimeConfig
org.freedesktop.SystemToolsBackends.UsersConfig
org.freedesktop.Tracker
org.gnome.GnomeVFS.Daemon
org.gnome.Rhythmbox
org.gnome.SettingsDaemon
org.gnome.Tomboy

这条命令的输出与ListActivatableNames的输出是不是基本相同?你能看懂上面这条命令吗?

(cat /usr/share/dbus-1/services/*|grep Name|awk -F= ‘print $2’|sort)

它将"/usr/share/dbus-1/services/"下所有文件交给grep筛选出包含“Name”的行。将包含“Name”的行交给awk处理,awk用"="作为列分隔符,取出第二列然后交给sort排序后输出。

"/usr/share/dbus-1/services/"目录就是dbus放service文件的地方。需要自动启动的服务器会在这个目录放一个service文件,例如:

$ cat /usr/share/dbus-1/services/dhcdbd.service

[D-BUS Service]
Name=com.redhat.dhcp
Exec=/usr/sbin/dhcdbd

Name是服务器的公共名,Exec是服务器的执行路径。在客户请求一个服务,但该服务还没有启动时。dbus会根据service文件自动启动服务。我们再写一个调用“org.fmddlmyy.Test”的Add接口的python脚本:

$ cat add.py
#!/usr/bin/env python
import dbus
bus = dbus.SessionBus()
obj = bus.get_object( 'org.fmddlmyy.Test', '/TestObj' )
iface = dbus.Interface(obj, 'org.fmddlmyy.Test.Basic')
sum = iface.Add(100, 999)
print sum

在启动“org.fmddlmyy.Test”服务器前调用这个脚本

$ ./add.py
会得到错误输出:

...
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name org.fmddlmyy.Test was not provided by any .service files

我们编辑一个service文件:

$ cat org.fmddlmyy.Test.service
[D-BUS Service]
Name=org.fmddlmyy.Test
Exec=/home/lvjie/work/dbus/hello-dbus3-0.1/src/example-service

把这个文件放到"/usr/share/dbus-1/services/"目录后,再执行add.py:

$ sudo cp org.fmddlmyy.Test.service /usr/share/dbus-1/services/
$ cd …/…/py
$ ./add.py
1099
这次dbus自动启动了服务器,我们的客户脚本得到了正确的输出,你有没有感到dbus的神奇?dbus在自动启动服务器后,不会自动关闭。如果没人管它,这个服务器会一直开着。

2.3.3、其它方法

再演示几个“org.freedesktop.DBus”接口的方法。

NameHasOwner判断有没有连接拥有指定的公共名:

$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.NameHasOwner string:"org.fmddlmyy.Test"
输出为:

method return sender=org.freedesktop.DBus -> dest=:1.31 reply_serial=2
   boolean true

GetNameOwner返回公共名对应的唯一名:

$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.GetNameOwner string:"org.fmddlmyy.Test"
输出为:

method return sender=org.freedesktop.DBus -> dest=:1.32 reply_serial=2
   string ":1.30"

GetConnectionUnixUser返回指定连接对应的服务器进程的Unix用户id:

$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixUser string:":1.30"
输出为:

method return sender=org.freedesktop.DBus -> dest=:1.33 reply_serial=2
   uint32 1000

这就是我的用户id:

$ id -u lvjie
1000

GetId返回消息总线的ID:

$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.GetId
输出为:

method return sender=org.freedesktop.DBus -> dest=:1.34 reply_serial=2
   string "dc209fee5f8ce01b0c23da0049668f11"

3 结束语

这一集有一些python代码。即使你没有学过python,我也建议你看一看、试一试。其实我也没有学过python。 小时候,好像听过什么德国人一边看说明书一边开飞机的笑话。这或许是吹牛,但对于程序员来说一边查手册一边用新语言写一些简单程序应该不算困难。 下一讲我们要写一个略大点的python程序。虽然我习惯于C/C++的事必躬亲,但不可否认python确实是很有魅力的语言, 难怪在嵌入式环境也有那么多人用python作原型开发。

参考文章:dbus实例讲解(二下):消息和消息总线

以上是关于linux 进程间通信 dbus-glib实例详解二(下) 消息和消息总线(ListActivatableNames和服务器的自动启动)(附代码)的主要内容,如果未能解决你的问题,请参考以下文章

linux 进程间通信 dbus-glib实例详解二(下) 消息和消息总线(ListActivatableNames和服务器的自动启动)(附代码)

linux 进程间通信 dbus-glib实例详解三(下) 数据类型和dteeth(类型签名type域)(层级结构:服务Service --> Node(对象object) 等 )(附代码)

linux 进程间通信 dbus-glib实例详解四(上) C库 dbus-glib 使用(附代码)(编写接口描述文件.xml,dbus-binding-tool工具生成绑定文件)(列集散集函数)

linux 进程间通信 dbus-glib实例详解一(附代码)(d-feet工具使用)

详解linux进程间通信-信号

[OS-Linux]详解Linux的进程间通信1------管道