dbus实例讲解2

本文深入解析D-Bus消息类型,包括method_call、method_return、error和signal,以及如何使用dbus-send和dbus-monitor工具进行操作。同时,介绍了消息总线作为路由器的角色,提供连接应用之间的消息传递,并列举了消息总线接口及其方法。通过实例展示了如何调用远程方法和监控总线消息。
摘要由CSDN通过智能技术生成

应用程序A和消息总线连接,这个连接获取了一个众所周知的公共名(记作连接A)。应用程序A中有对象A1提供了接口I1,接口I1有方法M1。应用程序B和消息总线连接,要求调用连接A上对象A1的接口I1的方法M1。

在上一讲的加法例子中,上面这段话可以实例化为:应用程序example-service和会话总线连接。这个连接获取了一个众所周知的公共名“org.fmddlmyy.Test”。应用程序example-servic中有对象“/TestObj”提供了接口“org.fmddlmyy.Test.Basic”,接口“org.fmddlmyy.Test.Basic”有方法“Add”。应用程序d-feet和会话总线连接,要求调用连接“org.fmddlmyy.Test”上对象“/TestObj”的接口“org.fmddlmyy.Test.Basic”的方法“Add”。

应用程序B调用应用程序A的方法,其实就是应用程序B向应用程序A发送了一个类型为“method_call”的消息。应用程序A通过一个类型为“method_retutn”的消息将返回值发给应用程序B。我们简单介绍一下D-Bus总线上的消息。

1、D-Bus的消息

上一讲说过最基本的D-Bus协议是一对一的通信协议。与直接使用socket不同,D-Bus是面向消息的协议。 D-Bus的所有功能都是通过在连接上流动的消息完成的。

1.1、消息类型

D-Bus有四种类型的消息:

  • method_call 方法调用
  • method_return 方法返回
  • error 错误
  • signal 信号

前面介绍的远程方法调用就用到了method_call和method_return消息。顾名思义,在发生错误时会产生error消息。如果把method_call看作打电话,那么signal消息就是来电了。后面还会详细讨论。

1.2、dbus-send和dbus-monitor

dbus提供了两个小工具:dbus-send和dbus-monitor。我们可以用dbus-send发送消息。用dbus-monitor监视总线上流动的消息。让我们通过dbus-send发送消息来调用前面的Add方法,这时dbus-send充当了应用程序B。用dbus-monitor观察调用过程中的消息。

启动example-service:

$ ./example-service 

在另一个控制台启动dbus-monitor:

$ dbus-monitor

dbus-monitor默认监视会话总线。执行:

$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test /TestObj org.fmddlmyy.Test.Basic.Add int32:100 int32:999

输出为:

method return sender=:1.21 -> dest=:1.22 reply_serial=2
   int32 1099

dbus-monitor的相关输出包括:

signal sender=org.freedesktop.DBus -> dest=(null destination) path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged
   string ":1.22"
   string ""
   string ":1.22"
method call sender=:1.22 -> dest=org.freedesktop.DBus path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=Hello
method call sender=:1.22 -> dest=org.fmddlmyy.Test path=/TestObj; interface=org.fmddlmyy.Test.Basic; member=Add
   int32 100
   int32 999
method return sender=:1.21 -> dest=:1.22 reply_serial=2
   int32 1099
signal sender=org.freedesktop.DBus -> dest=(null destination) path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged
   string ":1.22"
   string ":1.22"
   string ""

:1.22就是dbus-send在本次调用中与会话总线所建立连接的唯一名。:1.21是连接“org.fmddlmyy.Test”的唯一名。在以上输出中我们可以看到:1.22向“org.fmddlmyy.Test”发送method_call消息,调用Add方法。 :1.21通过method_return消息将调用结果发回:1.22。其它输出信息会在以后说明。

dbus-send的详细用法可以参阅手册。调用远程方法的一般形式是:

$ dbus-send [--system | --session] --type=method_call --print-reply --dest=连接名 对象路径 接口名.方法名 参数类型:参数值 参数类型:参数值

dbus-send支持的参数类型包括:string, int32, uint32, double, byte, boolean。

2、消息总线的方法和信号

2.1、概述

消息总线是一个特殊的应用,它可以在与它连接的应用之间传递消息。可以把消息总线看作一台路由器。正是通过消息总线,D-Bus才在一对一的通信协议基础上实现了多对一和一对多的通信。

消息总线虽然有特殊的转发功能,但消息总线也还是一个应用。其它应用与消息总线的通信也是通过1.1节的基本消息类型完成的。作为一个应用,消息总线也提供了自己的接口,包括方法和信号。

我们可以通过向连接“org.freedesktop.DBus ”上对象“/”发送消息来调用消息总线提供的方法。事实上,应用程序正是通过这些方法连接到消息总线上的其它应用,完成请求公共名等工作的。

2.2、清单

消息总线对象支持第一讲中提到的标准接口"org.freedesktop.DBus.Introspectable",我们可以调用org.freedesktop.DBus.Introspectable.Introspect方法查看消息总线对象支持的接口。例如:

$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect

输出为:

method return sender=org.freedesktop.DBus -> dest=:1.20 reply_serial=2
   string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
  <interface name="org.freedesktop.DBus.Introspectable">
    <method name="Introspect">
      <arg name="data" direction="out" type="s"/>
    </method>
  </interface>
  <interface name="org.freedesktop.DBus">
    <method name="Hello">
      <arg direction="out" type="s"/>
    </method>
    <method name="RequestName">
      <arg direction="in" type="s"/>
      <arg direction="in" type="u"/>
      <arg direction="out" type="u"/>
    </method>
    <method name="ReleaseName">
      <arg direction="in" type="s"/>
      <arg direction="out" type="u"/>
    </method>
    <method name="StartServiceByName">
      &l
要生成一个DBus service实例,需要遵循以下步骤: 1. 定义DBus service接口:首先需要定义你的DBus service接口,包括DBus接口名称、DBus对象路径、DBus接口方法和DBus接口信号。 2. 定义DBus service实现:接下来需要定义DBus服务的实现,实现DBus服务接口的所有方法和信号。 3. 注册DBus service实现:将DBus服务实现注册到DBus系统总线上,以便客户端可以通过DBus总线调用DBus服务。 4. 运行DBus service实例:最后,启动DBus服务实例并等待客户端的DBus调用。 下面是一个简单的DBus service实例生成的代码示例: ```python import dbus import dbus.service # 定义DBus service接口 class MyDBUSService(dbus.service.Object): def __init__(self): bus_name = dbus.service.BusName('com.example.MyService', bus=dbus.SessionBus()) dbus.service.Object.__init__(self, bus_name, '/com/example/MyService') # 定义DBus service方法 @dbus.service.method('com.example.MyService', in_signature='s', out_signature='s') def say_hello(self, name): return 'Hello, %s!' % name # 注册DBus service实现 myservice = MyDBUSService() # 运行DBus service实例 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) loop = gobject.MainLoop() loop.run() ``` 在上面的示例,我们首先定义了一个名为MyDBUSServiceDBus服务接口,并实现了一个名为say_hello的DBus方法。然后,我们注册了MyDBUSService服务实现,并在最后运行DBus服务实例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值