全部博文(685)
分类: 嵌入式
2014-11-11 15:26:04
前面一篇讲了DBus的 C 编程接口。现在开始解释一下 DBus 的基本概念,顺序反了,但和我的理解过程是一致的。看到 C 的编程接口之后,至少对于它的理解会有一定的感性认识。
DBus是用来进行进程间通信的。下面这张图展示了一些DBus的大部分东西,但是它太复杂了:
DBus 本身是构建在 Socket 机制之上。真正的通信还是由 Socket 来完成的。DBus 则是在这之上,制定了一些通信的协议,并提供了更高一层的接口,以更方便应用程序之间进行数据的交互。
在DBus的体系中,有一个常驻的进程 Daemon,所有进程间的交互都通过它来进行分发和管理。所有希望使用 DBus 进行通信的进程,都必须事先连上 Daemon,并将自己的名字注册到 Daemon 上,之后,Daemon会根据需要把消息以及数据发到相应的进程中。
首先使用
让应用程序和 DBus 之间取得连接。之后,使用函数
将自己的进程名字注册到 Daemon 上。(参考前篇的[共通用代码])。这样通信就有了基础了。
DBus 提供的最简单的一种通信方式是信号(Signal),应用程序可以发送一个信号到 Daemon 上,之后,Daemon 会根据信号的种类和谁希望得到信号等信息,把相应的数据发给每个希望得到信号的进程。也就是 Signal 具有广播的功能。信号具有两个基本的属性,一个是名称,用来标识各个不同的信号,一个是数据,信号是可以带一定的数据的。Signal 的通信过程可以用下面的图大概展示出来:
如果一个进程(比如 B )想接收接口名为 test.signal.Type 的信号,那么可以使用下面的函数向 Daemon 添加匹配信号,让 Daemon 知道自己对这种信号感兴趣。
然后, 进程 B 可以使用下面的函数来进行等待:
一旦有消息发送过来,进程 B 就可以通过 msg 取到相应的数据了。(参考前篇代码段[接收消息1、2] )
现在有一个进程 A,
到这里为止,已经涉及到了几个基本而又核心的概念,搞清楚它们,几乎就大概知道了 DBus 的使用方法了。
DBusMessage 是 DBus 中的核心数据结构。可以这样理解:DBus中传递消息数据的时候,就是通过它来传递的。对于使用者来说,DBusMessage 中存储了两种重要的信息,一种是为通信机制服务的各种 Name,一种是通信的数据本身。
各种名字(Name)
在前面用到的很多接口中都还有名称/路径字符串作为参数。
DBus Name: 在 DBus 中最为重要的名字是“Bus Name”,Bus Name 是一个每个应用程序(或是通信对象)用来标识自己用的。几乎可以当成是“IP”地址来理解。Bus Name有两种,一种是“Unique Connection Name”,是以冒号开头的,是全局唯一但“人类不友好”的命名,一种是“Well-know Name”,人类友好的。Bus Name 的命名规则是:
几个例子是:Unique Name :392-2.33 org.freedesktop.DBus 等等
DBus Name 是用来给应用程序进行标识自己的,所以每当程序连上 DBus Daemon 后,就会分配到一个 Unique Name,同时应用程序还可以要求自己分配另一个 Well-know name (通过 dbus_bus_request_name 函数)。
Interface name: DBus 也有 interface 这个概念,主要是用来为更高一层的框架使用方面而设定的。在 C API 这一层,你几乎可以无视这个概念,只需要知道这个一个“字符串”,并在消息匹配是被 DBus 使用到,会随着消息在不同的进程之前传递,从进程 A 发送一个消息或是数据到进程 B 时,其中必定会带有一个部分就是这个字符串,至于 B 进程怎么用(或是无视它)都可以。它的命名规则与 DBus Name 几乎是一样的,只有一点要注意,interface name 中不能带有“-”字符。
Object path:DBus 中的 object path,与 interface 一样,也只是个概念在更高一层的框架(QT Dbus)中才比较有用,在 C API 这一层,几乎可以无视这个概念,把它当成一个普通的字符串,根据通信的需要,用来做一种标识和区分。Object path 的命名规则是:/com/example/MusicPlayer1
一个 object path 的例子:/com/example/MusicPlayer1
Member name:Member 包含两种类型,一种是 Signal,一种是 Method。在大多数方面,他们几乎是一样的,除了两点:1. Signal是在总线中进行广播的,而Method是指定发给某个进程的。2. Signal 不会有返回,而 Method 一定会有返回(同步的或是异步的)。Member name的命名规则是这样的:
以 C API 的层面来看,Member name最大的作用就是在两个进程间共享“发出的消息的类型信息”。DBus 只能以 Signal / Method 来进行消息通信,这两种方式都允许在消息发出之前,在消息中 append 各种类型的数据,当通信的对方收到消息后,它就可以通过 Signal / Method 的名称知道如何把各种数据再解析出来。
到现在为止,已经介绍了三种最为重要的 Name,如果与的熟悉 windows 消息机制对比的话,我大概觉得,DBus Name 就是进程的 ID,有了这个你才能把消息发给指定的进程,object path ,interface等概念在“(QT等)高层框架中才有意义”,C API 级别的使用的话,可以无视它的概念,当成消息甄别用的信息就好了。 Member name 相当于 Message type,有了它你才知道怎么去解析发过来的数据。
下篇将会记录 DBusMessage 另一个主要的组成部分:通信数据。