D-Bus 是最初是为 Linux 开发的 IPC (进程间通信) 和 RPC (远程过程调用) 机制,采用 1 个统一协议替换替换现有的竞争 IPC 解决方案。它还被设计成允许在系统级进程 (譬如:打印机和硬件驱动程序服务) 和正常用户进程之间,进行通信。
它使用很快的二进制消息传递协议,适于同机通信 (由于它的低延迟和低开销)。目前,其规范的定义是通过
freedesktop.org
工程,且所有各方可用。
一般而言,通信是透过称为 Bus (总线,因此得名) 的中心服务器应用程序发生的,但应用程序直接到应用程序的通信也是可能的。当在 Bus (总线) 中进行通信时,应用程序可以查询哪些其它应用程序和服务可用,及按需激活它们之一。
当期望多对多通信时,使用 D-Bus 总线。为了达成这,要启动中心服务器,在任何应用程序可以连接到总线之前。此服务器负责追踪所连接的应用程序,并负责把消息从它们的源路由到其目的地。
此外,D-Bus 定义了 2 个知名总线 (称为系统总线和会话总线)。这些总线的特殊意义是它们具有定义良好的语义:一些服务被定义成能在其中一个或两个总线中被找到。
例如,希望查询附加到计算机中的硬件设备列表的应用程序,可能会与系统 Bus (总线) 中的可用服务通信,而提供打开用户 Web 浏览器的服务,将可能在会话 Bus (总线) 中找到。
在系统 Bus (总线),还可以找到允许各应用程序提供什么服务的有关限定。因此,可以相当确定,若存在某个服务,它是由受信任的应用程序提供的。
在较低级别,应用程序通过 D-Bus 相互发送消息进行通信。使用消息能中继远程过程调用、及与它们关联的回复和错误。当通过总线使用时,消息具有目的地,这意味着它们仅能路由到感兴趣各方,避免由于蜂拥 (或广播) 的拥塞。
一种特殊消息,称为信号消息 (概念基于 Qt 的 信号和槽 机制),不管怎样,没有预定义目的地。由于其目的是在一对多上下文中使用,所以信号消息被设计成在选择加入机制下工作。
Qt D-Bus 模块将低级消息概念完全封装成 Qt 开发者所熟悉的更简单、面向对象的方式。在大多数情况下,开发者无需担心消息的发送或接收。
当通过总线通信时,应用程序获得所谓的服务名称:这就是该应用程序选择被同一总线中,其它应用程序知道的方式。服务名称由 D-Bus 总线代理程序守护,用于将消息从一个应用程序路由到另一个应用程序。与服务名称类似的概念是 IP 地址和主机名:根据计算机提供给网络的服务,一台计算机通常具有一个 IP 地址,且可能具有一个或多个与其关联的主机名。
另一方面,若不使用总线,也不会使用服务名称。若再将其与计算机网络进行比较,这相当于点对点网络:由于对等方是已知的,因此不需要使用主机名来查找它 (或其 IP 地址)。
D-Bus 服务名称的格式,实际上非常类似于主机名:它是由点分隔的字母和数字序列。常见实践甚至是根据定义该服务的组织的域名,来命名服务名称。
例如,D-Bus 服务的定义通过
freedesktop.org
且可以在总线中找到以下服务名称:
org.freedesktop.DBus
像网络主机,应用程序通过导出对象向其它应用程序提供特定服务。这些对象是按层次组织的,很像父子关系的类派生自 QObject 占有的。不管怎样,一种差异是存在 "根对象" 概念 (被所有对象作为最终父级拥有)。
若继续与 Web 服务进行类比,对象路径等同于 URL 的路径部分:
像它们,D-Bus 对象路径的形成类似文件系统路径名:它们是以斜杠分隔的标签,各标签由字母、数字及 _ 下划线字符组成。它们必须始终以斜杠开头,且不能以斜杠结尾。
接口类似 C++ 抽象类和 Java 的
interface
关键词并声明在调用方和被调用方之间,建立的 "契约"。也就是说,它们建立的方法、信号和属性名是可用的,及期望来自任何一方的行为,当建立通信时。
Qt 使用非常类似的机制在其 插件系统 :C++ 中的基类关联唯一标识符,通过方式 Q_DECLARE_INTERFACE () 宏。
事实上,D-Bus 接口名称的命名方式与 Qt 插件系统的建议类似:标识符的构造通常来自定义该接口的实体的域名。
为便于记住命名格式及其用途,可以使用下表:
| D-Bus 概念 | 类比 | 名称格式 |
|---|---|---|
| 服务名称 | 网络主机名 | 点分隔 (看起来像主机名) |
| 对象路径 | URL 路径分量 | 斜杠分隔 (看起来像路径) |
| 接口 | 插件标识符 | 点分隔 |
在使用 D-Bus 开发应用程序时,有时,能够查看各应用程序跨总线发送和接收的消息的相关信息是有用的。
可以在每个应用程序的基础上启用此特征,通过设置
QDBUS_DEBUG
环境变量,在运行每个应用程序之前。例如,我们只可以启用调试,对于小车的
D-Bus 远程控制车
范例是通过以下方式运行控制器和小车的:
examples/dbus/remotecontrolledcar/controller/controller & QDBUS_DEBUG=1 examples/dbus/remotecontrolledcar/car/car &
有关消息的信息会被写入到发起应用程序的控制台。