ToB企服应用市场:ToB评测及商务社交产业平台

标题: Linux D-Bus 详解 [打印本页]

作者: 天津储鑫盛钢材现货供应商    时间: 昨天 13:35
标题: Linux D-Bus 详解
媒介

在构建复杂应用或服务时,经常会碰到历程间通信的题目。DBus 提供了一个高效、可靠的解决方案,使得差别步伐之间可以轻松地进行消息交换和远程调用。本篇文章将带你详细了解 DBus 的工作机制及如何在你的项目中有效利用这一技术。
什么是 D-Bus?

D-Bus 是 Linux 及其他类 Unix 系统下的一种历程间通信机制(IPC)。那什么是历程间通信机制(IPC)呢?IPC(Inter-process communication)是操纵系统提供给历程用于管理共享数据的一套机制,简单来说,如果历程 A 和历程 B 要进行通信(发送数据),就要通过 IPC,如下图所示:

除了 D-Bus,Linux 常见的历程间通信(IPC)还有如下几种:

既然有这么多 IPC,那为什么还需要 D-Bus 呢?这里就要说到 D-Bus 的出生背景,D-Bus 最初由 GNOME(桌面环境) 开发者 Havoc Pennington 发起,GNOME 和 KDE 作为两个主流的桌面环境,各自都有自己独立的历程间通信方案(如 GNOME 使用 Bonobo,KDE 使用 DCOP)。这两者的兼容性题目明显影响了 Linux 桌面应用步伐的整合和一致性。因此,D-Bus 的计划目的之一就是消除这些碎片化的通信机制,提供一个通用的 IPC 解决方案。
D-Bus 最初用于桌面环境,后来使用范围逐渐扩展,包含的系统服务越来越多。比方 NetworkManager 网络守护历程、BlueZ 蓝牙堆栈都使用 D-Bus 来提供其部分或全部的服务,systemd 也正促使传统的系统守护历程(如 logind)转换到 D-Bus 服务。所以 D-Bus 还有一个非常大的用途是用来进行硬件控制(好比通过 NetworkManager 服务来操纵 wifi 或通过 BlueZ 服务来操纵蓝牙)。
D-Bus 总线

D-Bus 提供了一种软件总线抽象,它将一组历程间的全部通信会合在一个共享的虚拟通道上。连接到总线的历程并不知道其内部实现细节,但 D-Bus 规范包管了全部连接到总线的历程都能通过它相互通信。

D-Bus 提供了两种总线:


D-Bus 的配置文件位于 /usr/share/dbus-1 目录中。系统总线和会话总线的配置文件 system.conf 和 session.conf 分别在 /etc/dbus-1 目录下。
D-Bus 通信模子

D-Bus 接纳了 客户端-服务器(CS)模子的通信方式,但它中心多了一层消息总线,消息总线起到中央枢纽的脚色,雷同 MQTT 的 broker。历程既可以提供服务也可以作为客户端请求服务。
要让某个历程提供一个服务或作为客户端请求一个服务,需要提供如下参数:


D-Bus 消息范例

D-Bus 支持 4 种范例的消息,消息范例决定了消息的路由方式、目的以及如何处置惩罚:


D-Bus 命令调试

在编写步伐来使用 D-Bus 之前,一般会先使用命令来测试我们想要的结果。D-Bus 提供了如下的命令以供我们通过命令来进行调试:

好比我想查看 org.freedesktop.NetworkManager 服务(一个网络管理工具)的 /org/freedesktop/NetworkManager 对象路径提供了哪些接口以及方法属性信号,可以使用如下命令:busctl introspect org.freedesktop.NetworkManager /org/freedesktop/NetworkManager。它会打印如下信息:
  1. NAME                                TYPE      SIGNATURE        RESULT/VALUE                             FLAGS
  2. org.freedesktop.DBus.Introspectable interface -                -                                        -
  3. .Introspect                         method    -                s                                        -
  4. org.freedesktop.DBus.Peer           interface -                -                                        -
  5. .GetMachineId                       method    -                s                                        -
  6. .Ping                               method    -                -                                        -
  7. org.freedesktop.DBus.Properties     interface -                -                                        -
  8. .Get                                method    ss               v                                        -
  9. .GetAll                             method    s                a{sv}                                    -
  10. .Set                                method    ssv              -                                        -
  11. .PropertiesChanged                  signal    sa{sv}as         -                                        -
  12. org.freedesktop.NetworkManager      interface -                -                                        -
  13. .ActivateConnection                 method    ooo              o                                        -
  14. .AddAndActivateConnection           method    a{sa{sv}}oo      oo                                       -
  15. .AddAndActivateConnection2          method    a{sa{sv}}ooa{sv} ooa{sv}                                  -
  16. .CheckConnectivity                  method    -                u                                        -
  17. .CheckpointAdjustRollbackTimeout    method    ou               -                                        -
  18. .CheckpointCreate                   method    aouu             o                                        -
  19. .CheckpointDestroy                  method    o                -                                        -
  20. .CheckpointRollback                 method    o                a{su}                                    -
  21. .DeactivateConnection               method    o                -                                        -
  22. .Enable                             method    b                -                                        -
  23. .GetAllDevices                      method    -                ao                                       -
  24. .GetDeviceByIpIface                 method    s                o                                        -
  25. .GetDevices                         method    -                ao                                       -
  26. .GetLogging                         method    -                ss                                       -
  27. .GetPermissions                     method    -                a{ss}                                    -
  28. .Reload                             method    u                -                                        -
  29. .SetLogging                         method    ss               -                                        -
  30. .Sleep                              method    b                -                                        -
  31. .state                              method    -                u                                        -
  32. .ActivatingConnection               property  o                "/"                                      emits-change
  33. .ActiveConnections                  property  ao               0                                        emits-change
  34. ......
复制代码
详细的用法可以通过 命令 --help 查看。
D-Bus 数据范例

在D-Bus 中,也有雷同编程语言中变量范例的概念,好比字符串范例、布尔范例等等,当我们调用一个方法,需要传入指定的参数范例,如果传的范例不对,则会导致调用方法失败。
范例分别如下两种:

基本范例有如下:

容器范例有如下:

D-Bus 用户空间库

差别的编程语言都提供了干系的库供应用步伐进行调用,一般常用的如下:

C++ 版代码示例

下面以 dbus-cxx 库为例,给出干系的 D-Bus 代码示例。
作为服务:
  1. #include <dbus-cxx.h>
  2. #include <thread>
  3. #include <chrono>
  4. double add(double param1, double param2) {
  5.     return param1 + param2;
  6. }
  7. int main() {
  8.     std::shared_ptr<DBus::Dispatcher> dispatcher = DBus::StandaloneDispatcher::create();
  9.     // 创建一个连接对象 `conn`,表示一个到 D-Bus 总线的连接。此处连接到用户会话总线。
  10.     std::shared_ptr<DBus::Connection> conn = dispatcher->create_connection(DBus::BusType::SESSION);
  11.     // 请求在 D-Bus 上注册服务名称 "dbuscxx.quickstart_0.server"。
  12.     // `DBUSCXX_NAME_FLAG_REPLACE_EXISTING` 标志表示如果该名称已存在,则替换原服务。
  13.     if (conn->request_name("dbuscxx.quickstart_0.server", DBUSCXX_NAME_FLAG_REPLACE_EXISTING) != DBus::RequestNameResponse::PrimaryOwner)
  14.         return 1;  // 如果无法获得该名称的所有权,程序退出。
  15.     // 创建一个对象,允许其他进程通过 D-Bus 调用该对象的方法。
  16.     // "/dbuscxx/quickstart_0" 是该对象在 D-Bus 上的路径。
  17.     // `DBus::ThreadForCalling::DispatcherThread` 表示该对象方法将在 D-Bus 分派线程中被调用。
  18.     std::shared_ptr<DBus::Object> object = conn->create_object("/dbuscxx/quickstart_0", DBus::ThreadForCalling::DispatcherThread);
  19.     // 创建一个方法 "add",该方法可以通过 D-Bus 调用。
  20.     // `sigc::ptr_fun(add)` 将 C++ 函数 `add` 转换为可以在 D-Bus 中使用的函数对象。
  21.     // 该方法接收两个 `double` 类型的参数并返回一个 `double` 类型的值。
  22.     object->create_method<double(double, double)>("dbuscxx.Quickstart", "add", sigc::ptr_fun(add));
  23.     // 让程序运行 10 秒钟,保持 D-Bus 服务的活跃。
  24.     // 在这段时间内,其他进程可以调用该服务的 `add` 方法。
  25.     std::this_thread::sleep_for(std::chrono::seconds(10));
  26.     return 0;
  27. }
复制代码
作为客户端:
  1. #include <dbus-cxx.h>
  2. #include <iostream>
  3. int main()
  4. {
  5.   std::shared_ptr<DBus::Dispatcher> dispatcher = DBus::StandaloneDispatcher::create();
  6.   std::shared_ptr<DBus::Connection> connection = dispatcher->create_connection( DBus::BusType::SESSION );
  7.   // 创建一个对象代理 `object`,它代表了 D-Bus 上的远程对象。
  8.   // 这里的代理对象代表了一个名为 "dbuscxx.quickstart_0.server" 的服务
  9.   // 和该服务上的对象路径 "/dbuscxx/quickstart_0"。
  10.   std::shared_ptr<DBus::ObjectProxy> object = connection->create_object_proxy("dbuscxx.quickstart_0.server", "/dbuscxx/quickstart_0");
  11.   // 创建方法代理 `add_proxy`,该代理方法将通过 D-Bus 调用远程服务的方法。
  12.   // 这里的代理方法代表服务对象上的 "add" 方法,它接受两个 `double` 类型的参数。
  13.   DBus::MethodProxy<double(double,double)>& add_proxy
  14.     = *(object->create_method<double(double,double)>("dbuscxx.Quickstart","add"));
  15.   double answer;
  16.   // 使用方法代理调用远程 D-Bus 服务的 `add` 方法。此方法是阻塞调用,直到远程方法执行完毕。
  17.   answer = add_proxy( 1.1, 2.2 );
  18.   std::cout << "1.1 + 2.2 = " << answer << std::endl;
  19.   return 0;
  20. }
复制代码
参考文献



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4