PySide6.QtDBus

详细描述

介绍进程间通信和远程过程调用与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 在其插件系统中使用了一种非常相似的机制:C++ 中的基类通过 Q_DECLARE_INTERFACE() 宏与唯一标识符关联。

D-Bus接口名称实际上是以类似于Qt插件系统建议的方式命名的:通常由定义该接口的实体的域名构建的标识符。

速查表

为了方便记忆命名格式及其用途,可以使用下表:

D-Bus 概念

类比

名称格式

服务名称

网络主机名

点分隔(“看起来像主机名”)

对象路径

URL路径组件

斜杠分隔(“看起来像路径”)

接口

插件标识符

点分隔

调试

在开发使用D-Bus的应用程序时,有时能够查看每个应用程序通过总线发送和接收的消息信息是很有用的。

此功能可以通过在运行每个应用程序之前设置QDBUS_DEBUG环境变量来按应用程序启用。例如,我们可以通过以下方式仅为D-Bus远程控制汽车示例中的汽车启用调试:

QDBUS_DEBUG=1 python examples/dbus/pingpong/pong.py

有关消息的信息将被写入启动应用程序的控制台。

使用模块

要包含模块类的定义,请使用以下指令:

import PySide6.QtDBus

进一步阅读

以下文档包含有关Qt的D-Bus集成功能的信息,并提供了有关通过总线发送和接收类型信息的机制的详细信息:

班级列表