• D-Bus


    D-Bus三层架构

    D-Bus是一个为应用程序间通信的消息总线系统, 用于进程之间的通信。它是个3层架构的IPC 系统,包括:

    1、函数库libdbus ,用于两个应用程序互相联系和交互消息。

    2、一个基于libdbus构造的消息总线守护进程,可同时与多个应用程序相连,并能把来自一个应用程序的消息路由到0或者多个其他程序。

    3、基于特定应用程序框架的封装库或捆绑(wrapper libraries or bindings )。例如,libdbus-glib和libdbus-qt,还有绑定在其他语言,例如Python的。大多数开发者都是使用这些封装库的API,因为它们简化了D-Bus编程细节。libdbus被有意设计成为更高层次绑定的底层后端(low-levelbackend )。大部分libdbus的 API仅仅是为了用来实现绑定。

    D-Bus进程通信简单框架


    DBUS中消息分为四类:

        1.  Methodcall消息:将触发一个函数调用 ;

        2.  Methodreturn消息:触发函数调用返回的结果;

        3.  Error消息:触发的函数调用返回一个异常 ;

        4.  Signal消息:通知,可以看作为事件消息。


    2.2 连接到总线
         进程间通信前,需要连接到总线。调用dbus_bus_get函数连接进程到总线,建立进程和总线之间的连接(DBusConnection)。建立连接后,需要为这个连接注册名称,方便后面对这个连接进行操作,调用dbus_bus_request_name函数对连接进行注册名称。

        建立连接和注册名称是在程序开始时执行,程序结束时,调用dbus_connection_close函数关闭一个连接。函数接口声明如程序清单 2‑1所示。

    程序清单 2-1 建立、注册名称和关闭连接

    DBusConnection  *dbus_bus_get  (DBusBusType  type,  DBusError   *error)             /*  建立和总线的连接  */

    int  dbus_bus_request_name  (DBusConnection   *connection,
                                  const char         *name,
                                  unsigned int        flags,
                                  DBusError        *error)                                   /*  注册连接名称      */

    void  dbus_connection_close  (DBusConnection  *connection)                           /*  关闭连接          */


    2.3 信号发送与接收
    2.3.1 信号发送
         DBUS中信号是一种广播的消息,当发出一个信号,所有连接到 DBUS 总线上并注册了接受对应信号的进程,都会收到该信号。

        进程发出一个信号前,需要创建一个 DBusMessage 对象来代表信号,然后追加上一些需要发出的参数,就可以发向总线了。发完之后需要释放消息对象。信号发送的函数声明如程序清单 2‑2所示。
    程序清单2-2  信号发送接口
    DBusMessage  *dbus_message_new_signal  (const  char  *path,
                                            const  char  *iface,
                                            const  char  *name)                       /*  创建信号类型消息      */
     
    void  dbus_message_iter_init_append  ( DBusMessage     *message,
                                DBusMessageIter  *iter)                /*  加入参数到信号        */
     
    dbus_bool_t  dbus_connection_send  ( DBusConnection  *connection,
                                          DBusMessage    *message,
                                          dbus_uint32_t    *serial)                       /*  发送信号到总线        */
     
    void  dbus_message_unref  (DBusMessage *message)                                 /*  释放消息              */


    2.3.2 信号接收
         进程接收信号时,需先告知总线进程感兴趣的消息,然后等待接收消息。信号接收函数声明如程序清单 2‑3所示。
    程序清单 2-3 信号接收接口
    void  dbus_bus_add_match  ( DBusConnection  *connection,
                                 const char        *rule,
                                 DBusError       *error)                                 /*  告知总线感兴趣的消息   */
     
    DBusMessage  *dbus_connection_pop_message  ( DBusConnection  *connection)         /*  接收消息               */
     
    dbus_bool_t  dbus_message_is_signal  (DBusMessage  *message,
                                           const char      *iface,
                                           const char     *signal_name)                      /*  判断消息是否为信号     */


    2.4 函数调用和提供函数调用
    2.4.1 函数调用
          调用一个远程函数与发送一个信号原理类似,需要先创建一个消息(DBusMessage),然后通过注册在 DBUS上的名称指定发送的对象。然后追加相应的参数,调用方法分为两种,一种是阻塞式的,另一种为异步调用。异步调用的时候会得到一个“DBusMessage *” 类型的返回消息,从这个返回消息中可以获取一些返回的参数。

        函数调用的函数声明如程序清单 2‑4所示。
    程序清单 2-4 函数调用接口
    DBusMessage  *dbus_message_new_method_call  (const char  *destination,
                                                  const char  *path,
                                                  const char  *iface,
                                                  const char  *method)                    /*  创建一个函数调用消息    */
     
    void  dbus_message_iter_init_append  (DBusMessage     *message,
                               DBusMessageIter  *iter)                     /*  为消息添加参数           */
     
    dbus_bool_t  dbus_connection_send_with_reply  (DBusConnection   *connection,
                                                    DBusMessage      *message,
                                                    DBusPendingCall  **pending_return,
                                                    int            timeout_milliseconds)       /*  发送消息                */
     
    void  dbus_pending_call_block  (DBusPendingCall  *pending)                           /*  阻塞等待返回值           */
     
    DBusMessage  *dbus_pending_call_steal_reply  (DBusPendingCall  *pending)             /*  获得返回消息            */
      
    dbus_bool_t  dbus_message_iter_init  (DBusMessage     *message,
                               DBusMessageIter  *iter)                     /*  获取参数                */


    2.4.2 接收函数调用
         提供远程函数调用,首先需告知总线进程感兴趣的消息,其次从总线获取消息并判定消息是方法调用。然后从消息中获取参数进行函数执行,最后创建返回消息,并发送消息至总线,由总线转发至调用的进程。函数声明如程序清单 2‑5所示。
    程序清单 2-5 接收函数调用接口
    void  dbus_bus_add_match  ( DBusConnection  *connection,
                                 const char        *rule,
                                 DBusError       *error)                                   /*  请求获取调用消息       */
     
    DBusMessage  *dbus_connection_pop_message  ( DBusConnection  *connection)           /*  从总线获取消息         */
     
    dbus_bool_t  dbus_message_is_method_call (DBusMessage  *message,
                                               const char     *iface,
                                               const char     *method)                       /*  判定消息是方法调用     */
      
    dbus_bool_t  dbus_message_iter_init  (DBusMessage     *message,
                               DBusMessageIter  *iter)                    /*  获取参数               */
     
    DBusMessage  *dbus_message_new_method_return  (DBusMessage *method_call)            /*  创建返回消息           */
     
    void  dbus_message_iter_init_append  ( DBusMessage     *message,
                                DBusMessageIter  *iter)                   /*  在消息中填入参数       */
     
    dbus_bool_t  dbus_connection_send  ( DBusConnection   *connection,
                                          DBusMessage     *message,
                                          dbus_uint32_t     *serial)                        /*  发送返回消息          */


    参考资料:

    http://blog.csdn.net/eastmoon502136/article/details/10044993

    https://blog.csdn.net/mr_wangning/article/details/60324291

    https://www.cnblogs.com/liyiwen/archive/2012/12/02/2798876.html

  • 相关阅读:
    ReentrantLock的实现语义与使用场景
    队列同步器详解
    设计模式--模板方法模式
    Synchronized及其实现原理
    JAVA线程基础
    JAVA内存模型
    java 线上问题定位工具
    JMX超详细解读
    Hexo
    [转]html5 video在安卓大部分浏览器包括微信最顶层的问题
  • 原文地址:https://www.cnblogs.com/klcf0220/p/11017219.html
Copyright © 2020-2023  润新知