如何使用 DBus 中已有的服务?

Posted

技术标签:

【中文标题】如何使用 DBus 中已有的服务?【英文标题】:How to use the existing services in DBus? 【发布时间】:2016-03-12 21:56:04 【问题描述】:

我可以使用 dbus 命令,如 dbus-send 等。但我不知道如何有效地使用 dbus 的 api 来编写示例应用程序。谁能告诉我如何接收来自 dbus 的数据。我不知道如何使用 dbus 中的现有服务,例如 org.freedesktop.NetworkManager

请告诉我访问和使用 dbus 服务的正确方法。 请发布一些示例,并建议我在使用服务时必须遵循哪些规则。

我正在寻找1)如何将我们自己的服务添加到系统/会话总线。同时,如何接收该服务。 2)如何使用现有的服务,就像org.freedesktop.NetworkManager.GetDevices一样。我想要实现代码

【问题讨论】:

【参考方案1】:

您的问题很开放,因为您没有说明任何要求,例如您计划在示例应用程序中使用什么语言和绑定(如果有)。

当您询问 D-Bus 的 API 时,这可能意味着不同的事情,具体取决于您打算编写代码的抽象级别。我将假设您打算使用与 D-Bus 的低级 API 集成的绑定,即您将使用的 API 比低级 D-Bus C API 具有更高的抽象级别。

在 python 中,使用一个可用的绑定 dbus-python,一个非常简单的服务可能如下所示:

import gobject
import dbus
import dbus.service

from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)


OPATH = "/temp/Test"
IFACE = "temp.Test"
BUS_NAME = "temp.Test"


class MyService(dbus.service.Object):
    def __init__(self):
        bus = dbus.SessionBus()
        bus.request_name(BUS_NAME, dbus.bus.NAME_FLAG_REPLACE_EXISTING)
        bus_name = dbus.service.BusName(BUS_NAME, bus=bus)
        dbus.service.Object.__init__(self, bus_name, OPATH)

    @dbus.service.method(dbus_interface=IFACE, in_signature="s")
    def Echo(self, message):
        return "received: " + message


if __name__ == "__main__":
    my_service = MyService()
    loop = gobject.MainLoop()
    loop.run()

然后可以使用dbus-send 调用Echo 方法,如下所示:

dbus-send --session --print-reply --dest=temp.Test /temp/Test temp.Test.Echo string:"hello"

继续 Python 示例,上述服务的客户端可能如下所示:

import dbus

bus = dbus.SessionBus()
the_service = bus.get_object("temp.Test", "/temp/Test")
service_interface = dbus.Interface(service_object, dbus_interface="temp.Test")

print service_interface.Echo("hello")

有关dbus-python 的详细信息,您可以查看此tutorial。

扩展客户端示例,调用org.freedesktop.NetworkManager.GetDevices的一种方式是:

import dbus

bus = dbus.SystemBus()
service_object = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
service_interface = dbus.Interface(service_object, dbus_interface="org.freedesktop.NetworkManager")

print service_interface.GetDevices()

因此,一般而言,您需要了解您选择的语言存在哪些绑定,然后了解您想要与之交互的任何特定服务的 API。任何有关如何与服务交互的特定规则都应记录为 API 或设计文档等的一部分。

在客户端,您通常可以选择执行同步或异步调用(如果绑定和语言支持),这将对您的设计产生影响。

【讨论】:

以上是关于如何使用 DBus 中已有的服务?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 dbus 和 NetworkManager 激活连接

如何防止从表中已有的值派生的表中的某些值组合?

django如何连接Mysql中已有的数据库

如何从控制台创建 dbus 服务?

如何在没有桌面环境的 CentOS 中使用 dbus

如何防止 Maven 为我的仓库中已有的工件下载 maven-metadata.xml?