zoukankan      html  css  js  c++  java
  • dbus 消息和消息总线实例讲解-二

    转自:http://www.fmddlmyy.cn/text53.html

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

    运行:

    $ 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的脚本:

    $ 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的简洁会有更深刻的感触。如果你执行:

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

    你会得到:

    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的输出是不是基本相同?你能看懂上面这条命令吗?它将"/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。 小时候,好像听过什么德国人一边看说明书一边开飞机的笑话。这或许是吹牛,但对于程序员来说一边查手册一边用新语言写一些简单程序应该不算困难。 

  • 相关阅读:
    autoLayout适配
    iOS FMDB 无法更新二进制数据的问题
    iOS 数据库操作崩溃提示“ int rc = sqlite3_step([_statement statement]);”或者提示“ rc = sqlite3_step(pStmt);”
    iOS点击cell时,控件背景色消失的解决方法
    UISegmentedControl 的使用
    自定义cell侧滑删除
    iOS设置cell选中时文字颜色的变化
    iOS 如何在Label中显示html的文本
    iOS 单例的销毁
    类似微信聊天界面加载历史记录的样式
  • 原文地址:https://www.cnblogs.com/noxy/p/9948461.html
Copyright © 2011-2022 走看看