Dbus组成和原理

2019-07-13 08:42发布

  在LINUX系统下写开源代码的程序员,对DBUS应该是不会再陌生了。它的低时延和低消耗等优点吸引了很多人的目光,因为我们现在开发的平台,很多设计到DBUS这个通讯机制,所以我花了比较多的时间去熟悉它。通过这段时间的学习,把笔记也做一下,今天先介绍什么DBUS。 什么是DBUS? DBUS是实质上一个适用于桌面应用的进程间的通讯机制,即所谓的IPC机制。适合在同一台机器,不适合于INTERNET的IPC机制。DBUS不是一个为所有可能的应用的通用的IPC机制,不支持其他IPC机制的很多特性。DBUS提供了一个低时延、低消耗的IPC通讯,因为它采用了二进制的数据交换协议,不需要转换成文本化的数据进行交换,DBUS提供了面向多重对象系统的包装,可以在原有的面向对象的应用框架下使用DBUS,不需要学习新的概念和规范等。 DBUS是支持一对一和多对多的对等通讯,在一对一的直接通讯时,两个应用程序连接在一起,这是最简单的工作方式。在多对多的通讯时,这就需要一个叫DBUS后台的角 {MOD}去分转,一个应用程序发消息给另外一个应用程序,先到达后台,再让后台将信息发送到目的应用程序。在这里DBUS后台就充当着一个路由器的角 {MOD}。 DBUS包含了系统更新通知,如插入新设备通知、新软件安装通知等,和桌面应用的交互协作能力,可以作为文件系统监控器和配置服务器。 Dbus由对象、消息、连接、Dbus后台几部分组成。 对象是一个独立的处理消息的实体。对象有一个或多个接口,在每个接口有一个或多个的方法,每个方法实现了具体的消息处理。在一对一的通讯中,对象通过一个连接直接和另一个客户端应用程序连接起来。在多对多的通讯中,对象通过一个连接和Dbus后台进程连接起来。对象有一个路径用于指明该对象的存放位置,消息传递时通过该路径找到该对象。 客户端应用是一个桌面应用程序,是请求消息的发起者。客户端应用通过和自身的相连的一个连接将请求消息发送出去,也通过该连接接收回应的消息、错误消息、系统更新消息等。在一对一的通讯中,请求消息直接到达对象。在多对多的通讯中,请求消息先到达Dbus后台,Dbus后台将消息转发到目的对象。 连接是一个双向的消息传递通道。一个连接将对象和Dbus后台或客户端应用连接起来,连接支持非阻塞式的异步消息发送和阻塞式的同步消息发送。消息通过连接到达目的端后,连接会将挂起在该连接上的进程唤醒,由该进程将消息取走。每个连接都有一个唯一的名字和可选的其他多个名字,用于在多对多通讯时指明消息的发送者和接收者。 连接基于操作系统提供的通讯端口实现消息的交换,现在基于的通讯端口有三种,分别是UNIXsocketTCP/IP、管道(调试时用)。通讯端口拥有一个地址,服务器在这个地址上监听,客户端则连接到这个地址上。 消息是DbusIPC机制中的一个信息传递媒介。调用者将调用的方法、方法的参数打包进一个消息,接收者将方法和参数从消息中解包出来,执行这个方法调用。执行完后,将结果打包进返回消息中,返回给调用者。消息有四种类型,分别是方法调用消息、结果返回消息、错误消息、信号消息。这里的信号消息是主动发送的事件,如新设备插入、文件更改的事件等。 Dbus后台是在多对多通讯时用来转发消息,管理连接的一个后台进程。每个Dbus后台都和多个连接关联,其内部维护了连接名和连接实体的映射关系。Dbus后台就象一个路由器,将从发送者连接得到的消息转发到由消息中的接收者连接名指定的接收者连接中。 Dbus后台有多个。有一个用于和系统通讯,监控系统更新事件,其类型为DBUS_BUS_SYSTEMDbus后台。每个桌面会话(session)有一个用于多个桌面应用之间相互通讯,其类型为DBUS_BUS_SESSIONDbus后台。一般至少有两个Dbus后台,一个系统用,一个桌面会话用。系统用的Dbus后台只能处理系统的消息,桌面会话用的Dbus后台只能处理桌面会话应用的消息。 1、客户端。 在客户端使用DBUS比较简单,首先,从DBUS_BUS_SESSION类型的DBUS后台获得一个连接,再从这个连接创建得到一个对象的代理,以后对对象的所有操作都将通过这个代理来完成。 得到服务代理后,可以在应用程序的各个地方通过对象代理的方法使用函数想对象发出一个方法调用的消息。请求对象的服务,可以发送异步的方法(异步服务),也可以发送同步方法(同步服务),方法是同步还是异步有对象定义。 2、服务端。 在服务器进程启动后,调用函数dbus_g_object_type_install_info将对象的安装信息结构告诉DBUS,随后,从DBUS_BUS_SESSION类型的DBUS获得一个连接,再从这个连接得到一个DBUS对象的代理。通过这个DBUS代理调用方法RequestName为这个连接得到一个命名,客户端应用可以使用这个名字将请求消息发送到连接。接着,服务器进程创建一个指定类型的对象(glib对象)。 其中安装信息由XML文件,通过dbus-binding-tool转换成对象的头文件。 3、消息。 消息由消息头和消息体组成。消息头由消息的固有字段信息组成。消息体由一串字符串值组成。消息体的每个字符串值的意义由消息头中的描述指定,消息头的长度必须是8的倍数,相应的,消息体由8的倍数处开始。