【问题标题】:Use DBus daemon to exchange message from C application to python application使用 DBus 守护进程从 C 应用程序到 python 应用程序交换消息
【发布时间】:2016-09-19 16:08:31
【问题描述】:

您好,我是 DBus 守护程序的新手,希望在 C 应用程序和 python 应用程序之间完成简单的消息交换,它们运行在自定义的类 linux 环境中。我的理解是

  1. 首先,从 init 文件启动 dbus-daemon
  2. 将C应用和python应用注册到D-BUS
  3. 发送消息 (这只是一个简单的字符串)在这 2 个应用程序之间的总线上。

我的问题是关于上面的 (2) 和 (3)。 C应用和python应用如何注册到同一条总线上?

另外,需要调用哪些 API 在这 2 个应用程序之间发送字符串消息?

【问题讨论】:

    标签: python linux dbus


    【解决方案1】:

    [你要求简单的消息传递]

    你真的需要 DBus 吗?

    如果您要求在 C 应用程序和 Python 之间进行简单的消息传递,为什么不使用 Rabbit/ZeroMQ 之类的消息传递库呢?这些已经解决了与传递/接收消息相关的所有问题。

    而且,如果您想将依赖关系降至最低,您可以使用 UNIX 套接字甚至一些简单的 TCP/UDP 数据报。

    编辑:由于我试图说服您研究 ZeroMQ 作为您的 IPC 平台以及它是多么简单,所以这里有一个示例 C“客户端”向服务器发送完整的数据报,服务器会回复。

    ZeroMQ Client Example in C:

    // Hello World client
    #include <zmq.h>
    #include <string.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main ( void )
    {
        printf ( "Connecting to hello world server…\n" );
        void *context   = zmq_ctx_new ();
        void *requester = zmq_socket ( context, ZMQ_REQ );
        zmq_connect ( requester, "tcp://localhost:5555" );
    
        int request_nbr;
        for ( request_nbr = 0; request_nbr != 10; request_nbr++ ) {
            char buffer [10];
            printf ( "Sending Hello %d…\n", request_nbr );
            zmq_send ( requester, "Hello", 5, 0 );
            zmq_recv ( requester, buffer, 10, 0 );
            printf ( "Received World %d\n", request_nbr );
        }
        zmq_close (requester);
        zmq_ctx_destroy (context);
        return 0;
    }
    

    服务器也一样简单:

    ZeroMQ Server Example in C

    // Hello World server
    
    #include <zmq.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <assert.h>
    
    int main ( void )
    {
        // Socket to talk to clients
        void *context   = zmq_ctx_new ();
        void *responder = zmq_socket ( context, ZMQ_REP );
        int rc = zmq_bind ( responder, "tcp://*:5555" );
        assert ( rc == 0 );
    
        while ( 1 ) {
            char buffer [10];
            zmq_recv ( responder, buffer, 10, 0 );
            printf ( "Received Hello\n" );
            sleep ( 1 );                                // Do some 'work'
            zmq_send ( responder, "World", 5, 0 );
        }
        return 0;
    }
    

    【讨论】:

    • 我正在研究 DBUS,因为它抽象出套接字的低级细节。 C 应用程序可以连续发送字符串消息,Python 应用程序需要全部接收。这个过程永远运行。
    • ZeroMQ/RabbitMQ 具有相同的属性(您只需接收“捆绑”数据,您无需解开它们或担心分帧/分页/不完整数据等,每个数据帧都进来整体),您将受益于它是完全可移植的。这两个应用程序都可以在具有相同内部通信框架的 Windows 或 OSX 中运行。
    • OP 要求提供有关 DBUS 的信息,这是一个消息传递系统。 ZeroMQ/RabbitMQ/ApacheMQ 等是更大的平台,相比之下需要更多的资源。通常它们在自己的虚拟机/硬件上运行,并在服务器之间传递消息。 DBUS 仅限于同一系统上的消息,并且速度非常快且重量轻。
    【解决方案2】:

    每个 Linux 系统上都有两个默认总线 - 系统总线(为所有用户共享,为系统服务而设计)和会话总线。所有 DBus 库都可以让您轻松连接到其中一个总线。

    然后,在接收进程中,您需要拥有一个总线名称(一个可以让其他进程找到您的字符串),并注册一个提供一些方法的对象。然后你就可以从另一个进程调用这些方法了。

    C 的最佳 DBus API 是 https://developer.gnome.org/gio/stable/GDBusConnection.html,Python 的最佳 API 是 https://github.com/LEW21/pydbus

    【讨论】:

    • 其实只有系统总线默认启动。用户总线必须由用户启动。
    • 有没有办法将消息从守护进程发送到某个会话总线?可能存在许多会话总线——每个会话总线。我知道如何调用 ConsoleKit 来获取会话名称(通过 pid),但不知道如何利用这些数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-13
    • 2012-01-23
    • 1970-01-01
    • 2023-03-10
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多