代理对象用来表示其他的remote object。当触发了proxy对象的method时,将会在D-Bus上发送一个method_call的消息,并等待答复,根据答复返回。总线上的对象一般通过代理来访问。总线上的对象位于客户进程以外,而客户可以调用本地接口与对象通信,此时,本地接口充当了代理的角色。当触发了代理对象的方法时,将会在D-Bus上发送一个method_call的消息,并等待答复返回,就象使用一个本地对象一样。一些语言的代理支持“断线重连”。比如所连接的对象在某段时间里暂时断开了与总线的连接,代理会自动重连到相同的连接名并重新找到对象,程序甚至不会知道目标对象有段时间不可用。并不是所有的语言都支持这一特性,在GLib中的两种代理中的一种支持。比如不用代理时的代码如下: 服务是 D-BUS 的最高层次抽象,服务的实现当前还在不断发展变化。应用程序可以通过一个总线来******一个服务,如果成功,则应用程序就已经获得了服务。其他应用程序可以检查在总线上是否已经存在一个特定的服务,如果没有可以要求总线启动它。服务是 D-BUS 的最高层次抽象,服务的实现当前还在不断发展变化。应用程序可以通过一个总线来******一个服务,如果成功,则应用程序就已经获得了服务。其他应用程序可以检查在总线上是否已经存在一个特定的服务,如果没有可以要求总线启动它。当通过总线进行通信时,应用程序会获取服务名称。服务名称是应用程序如何选择同一总线上的其他应用程序的依据。服务名称由总线守护进程进行代理,用于将消息从一个应用程序路由到另一个应用程序。服务名称的类似概念是IP******和主机名:计算机通常具有一个IP******,并且根据其向网络提供的服务,可以具有与之相关联的一个或多个主机名。另一方面,如果不使用总线,服务名称也不会使用。如果再将它与计算机网络进行比较,这将等同于点到点网络:因为对等方是已知的,所以不需要使用主机名来查找它或它的IP******。总线服务名称的格式实际上与主机名非常相似:它是字母和数字的点分隔序列。常见的做法是根据服务定义的组织的域名来命名自己的服务名称。例如,D-Bus服务由义,可以使用org.freedesktop.DBus服务名称在总线上找到它。 A、method_call方法调用B、method_return方法返回C、error错误D、signal信号代理中的远程对象调用涉及到了消息总线以及method_call和method_return两类消息。消息有消息头(header)和消息体(body)。消息头包含消息体的路由信息,消息体是净荷,通常包含的是参数。消息头通常包含发送进程的连接名(Bus Name)、方法或者信号名等等,其中有一字段是用于描述消息体中的参数的类型的,例如“i”标识32位整数,“ii”表示2个32位整数。2、调用method的流程 A、在发送method_call消息时,如果使用了代理,进程A要调用进程B的某方法,不用构造method_call消息,只需调用代理的本地方法,代理会自动生成method_call消息发送到消息总线上。B、如果使用底层API,进程A需要构造一个method_call消息。method_call消息包含对应进程B的连接名、方法名、方法所需参数、进程B中的对象路径和进程B中声明此方法的接口。C、将method_call消息发送到消息总线上。D、信息总线检查消息头中的目的连接名,当找到一个进程与此连接名对应时发送消息到该进程。当找不到一个进程与此连接名对应时,返回给进程A一个error消息。E、进程B解析消息,如果是采用底层API方式,则直接调用方法,然后发宋应答消息到消息总线。如果是D-BUs高级API接口,会先检测对象路径、接口、方法名称,然后把消息转换成对应的本地对象(如GObject,QT中的QObject等)的方法,调用本地对象方法后再将应答结果转换成应答消息发给消息总线。F、消息总线接收到method_return消息,将把method_return消息直接发给发出调用消息的进程。消息总线不会对总线上的消息进行重排序。如果发送了两条消息到同一个进程,将按照发送顺序接收到。接收进程不需要按照顺序发出应答消息,例如在多线程中处理这些消息,应答消息的发出是没有顺序的。消息都有一个序列号可以与应答消息进行配对。3、发送signal的流程 |