DBUS入门笔记

网友投稿 1247 2022-08-27

DBUS入门笔记

DBUS入门笔记

DBUS简介

学习网址:​​ libdbus,消息分发的守护进程Dbus daemon,应用程序框架的封装库或绑定 (For example, libdbus-glib and libdbus-qt)

libdbus仅仅支持one-to-one connection

关于传递,对象是message = header (filed) + body (param) header常包括body中的数据类型信息。

DBUS的应用场景: 同一会话中的桌面应用程序 桌面应用程序和OS(系统级别的守护进程)

DBUS可以解决传统Linux IPC不能应付的远端系统管理员问题:

in current Linux support is that policies with any sort of dynamic "interact with user" component aren't currently supported. For example, that's often needed the first time a network adapter or printer is connected, and to determine appropriate places to mount disk drives. It would seem that such actions could be supported for any case where a responsible human can be identified: single user workstations, or any system which is remotely administered. This is a classic "remote sysadmin" problem, where in this case hotplugging needs to deliver an event from one security domain (operating system kernel, in this case) to another (desktop for logged-in user, or remote sysadmin). Any effective response must go the other way: the remote domain taking some action that lets the kernel expose the desired device capabilities. (The action can often be taken asynchronously, for example letting new hardware be idle until a meeting finishes.) At this writing, Linux doesn't have widely adopted solutions to such problems. However, the new D-Bus work may begin to solve that

DBUS和其他IPC相比具有的特点:

异步处理的二进制协议

安全可靠的连接

消息总线是守护进程

通信机制的部署与实现都是明确的

和DCOP通信机制类似

安全特性,支持系统消息

Object Path 是用于让上层绑定找到native object(比如QObject,GObject)

接口 DBus使用了字符串定义来表示不同的interface,接口包括了信号和方法。

代理 proxy object用来代表远端进程中的对象。 代理给开发者简化了不少工作量。开发者可以使用代理调用远端对象的方法并得到返回值,这就像是调用本地方法一样简单。 伪代码比较:

this: Message message = new Message("/remote/object/path", "MethodName", arg1, arg2); Connection connection = getBusConnection(); connection.send(message); Message reply = connection.waitForReply(message); if (reply.isError()) { } else { Object returnValue = reply.getReturnValue(); } Programming with proxies might look like this: Proxy proxy = new Proxy(getBusConnection(), "/remote/object/path"); Object

Bus name 当应用程序连接上bus daemon, daemon会立刻给该应用程序分配一个独一无二的connection name。它通常是以冒号开头。 与之对应,我们可以定义一个容易识别的domain name,与dbus name对应。

Dbus Address 指明server在哪里监听,client在哪里连接 一般,我们使用Dbus Daemon来分发消息,所以address由环境变量决定。但也可以重新定义自己的server,这样的话需要指明依赖于server name上的通信机制。

概念图:Address -> [Bus Name] -> Path -> [Interface] -> Method 被方括弧包围的对象是开发者不定义要提供的,需要分情况判断。

4种类型的message call message(调用object的函数),return message(返回计算的结果),error message(调用函数发生异常),signal message(emit signal时产生) 在调用远端方法的过程中,DBUS有两种message发挥着重要作用,分别是call message和return message。在call message中包含着一种序列号,return message具有相同的序列号,这样就具备了匹配的作用。 call message包括:远端进程的bus name,函数名,函数参数,object path,接口名(可选)

发送信号 Dbus也能发送信号,通过绑定,会有接收者来作出反应。

QTDBUS 学习案例:remotecontrolledcar

学习网址:​​class="data-table" data-id="t7a7e9d1-NBjOFlQT" data-transient-attributes="class" data-width="1162px" style="width: 100%; outline: none; border-collapse: collapse;">

D-Bus Concept

Analogy

Name format

Service name

Network hostnames

Dot-separated (“looks like a hostname”)

Object path

URL path component

Slash-separated (“looks like a path”)

Interface

Plugin identifier

Dot-separated

例子: remotecontrolledcar object path:/com/trollech/examples/car interface name:org.example.Examples.CarInterface 服务端注册服务:

; connection.registerObject("/Car", car); connection.registerService("org.example.CarExample");

XML产生接口

Qt D-Bus XML compiler 是 qdbusxml2cpp,这两者的产出:the interface (proxy) class or the adaptor class(服务端) interface: pro文件加上 ​​​DBUS_ADAPTORS += car.xml​​​ 产生头文件 ​​​qdbusxml2cpp -p car_interface.h: car.xml​​​ 产生cpp文件 ​​​qdbusxml2cpp -i car_interface.h -p :car_interface.cpp car.xml​​​ adaptor: pro文件加上 ​​​DBUS_INTERFACES += car.xml​​​ 调用相关的命令 产生头文件 ​​​qdbusxml2cpp -a car_adaptor.h: car.xml​​​ 产生cpp文件 ​​​qdbusxml2cpp -i car_adaptor.h -a :car_adaptor.cpp car.xml​​

客户端 访问远程的对象:

#include "car_interface.h"car = new org::example::Examples::CarInterface("org.example.CarExample", "/Car", QDBusConnection::sessionBus(), this);

关于CarInterface:

typedef ::OrgExampleExamplesCarInterfaceInterface CarInterface;/* * Proxy class for interface org.example.Examples.CarInterface */class OrgExampleExamplesCarInterfaceInterface: public QDBusAbstractInterfaceOrgExampleExamplesCarInterfaceInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);//QDBusAbstractInterface 提供了D-Bus的接口,用于本地访问远端的接口。

效果:

在mac上貌似没有dbus-daemon,需要自己-,配置 我安装后的目录是 ​​​/usr/local/Cellar/dbus/1.12.8/​​​ Mac上由Launchd管理守护进程,有点像linux中的init。 为了让dbus-daemon成为守护进程,我们需要将她的service plist文件放到Launchd的配置目录中。 这些目录有:

# 登陆后程序启动~/Library/LaunchAgents/Library/LaunchAgents/System/Library/LaunchAgents# 系统启动后程序启动/Library/LaunchDaemons/System/Library/LaunchDaemons

dbus安装目录下面有 org.freedesktop.dbus-session.plist label string即之前提到过的service name

Label org.freedesktop.dbus-session ProgramArguments /usr/local/Cellar/dbus/1.12.8/bin/dbus-daemon --nofork --session Sockets unix_domain_listener SecureSocketWithKey DBUS_LAUNCHD_SESSION_BUS_SOCKET

他可以被放在:​​/Users/weiyang/Library/LaunchAgents​​​ 我的mac上lantern是开机自启的,所以我仿照​​​org.getlantern.plist​​​在ProgramArguments的​​​​​下面 加上了如下的key。

RunAtLoad

并将她的文件属性改成:

然后重启登陆,可以发现有了dbus-daemon

然后mac上也能运行了:

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:QT enVocabulary工程打包问题记录
下一篇:【VTK】使用vtkActor2D添加polyline
相关文章

 发表评论

暂时没有评论,来抢沙发吧~