Qt D-Bus 概述
D-Bus 是一个跨进程通信(IPC)和远程过程调用(RPC)机制,最初为 Linux 开发,以用一个统一的协议替换现有的和竞争的 IPC 解决方案。它还被设计为允许系统级进程(如打印机和硬件驱动程序服务)与普通用户进程之间进行通信。
它使用快速、二进制消息传递协议,由于其低延迟和低开销,特别适合本机通信。其规范目前由 freedesktop.org
项目定义,并对所有参与者开放。
通常,所有通信都通过一个名为“总线”的中央服务器应用程序进行,但也可以直接进行应用程序之间的通信。在总线上进行通信时,应用程序可以查询哪些其他应用程序和服务可用,并在需要时激活其中一个。
总线
在需要多对多通信时使用 D-Bus 总线。为此,在任何应用程序可以连接到总线之前,都会启动一个中央服务器。该服务器负责跟踪连接的应用程序,并且适当地将消息从其源头路由到其目的地。
此外,D-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在其插件系统中使用非常类似的机制:通过Q_DECLARE_INTERFACE()宏将C++的基类与唯一的标识符相关联。
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 &
消息信息将被写入应用程序启动的命令行控制台。
© 2024 Qt 公司有限公司。本文档中的文档贡献是各自所有者的版权。本文档是根据由自由软件开发基金会发布的 GNU 自由文档许可版本 1.3 许可的。Qt 及相关的标志是芬兰及/或其他国家的 The Qt 公司的商标。所有其他商标均为其各自所有者的财产。