首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使D总线服务器端调用为异步?

如何使D总线服务器端调用为异步?
EN

Stack Overflow用户
提问于 2017-08-06 07:02:04
回答 1查看 3.1K关注 0票数 3

对于我的项目,我使用DBUS作为IPC在QT应用程序(客户端)和我的服务守护进程(Server GIO / GDBUS )之间进行交互。在客户端,使用QDBusPendingCallWatcher异步调用方法。

但是在服务器端,如何使方法调用作为异步呢?根据我的理解,"g_dbus_method_invocation_return_value“将返回响应,输出参数使方法调用成为同步。

我可以想到的一种方法是使用g_dbus_method_invocation_return_value返回中间响应,然后一旦接收到最终响应,就会以信号的形式发出最终响应。

示例代码:-

代码语言:javascript
复制
//Method invocation      

static void handle_method_call(GDBusConnection *conn,
                               const gchar *sender,
                               const gchar *object_path,
                               const gchar *interface_name,
                               const gchar *method_name,
                               GVariant *parameters,
                               GDBusMethodInvocation *invocation,
                               gpointer user_data)

{

    if (!g_strcmp0(method_name, "Scan")) {
        guint8 radiotype = 0;
        guint8temp_resp = 0 ;
        g_variant_get(parameters, "(y)", radiotype);
        // Async Function Call and takes very 
        // long time to return final response as needs to scan whole radio band 
        temp_resp = RadioScan(radiotype); 

        g_dbus_method_invocation_return_value(invocation, g_variant_new("(y", temp_resp)); // return intermediate response to client  and when final response is received then  emit the signal
        g_free(response);
    }
}
// Final scan response callback function
static gboolean on_scanfinalresponse_cb (gpointer user_data)
{

    GDBusConnection *connection = G_DBUS_CONNECTION (user_data);

    GVariantBuilder *builder;

    GVariantBuilder *invalidated_builder;

    GError *error;
    g_dbus_connection_emit_signal (connection,
                                   NULL,
                                   "/org/example/test",
                                   "org.example.test",
                                   "ScanFinalResponse",
                                   g_variant_new ("(s)",
                                                  builder),
                                   &error);
    g_assert_no_error (error);
    return TRUE;
}

请让我知道它是正确的方法,还是有更好的方法来实现上述情况下的异步调用?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-06 10:59:53

但是在服务器端,如何使方法调用作为异步呢?

这里有两个概念可能是用“异步”来指的,而D总线(或GDBus)在这两个概念中都不限制您。

  1. API设计:如果您可以修改实际公开的API,当然可以创建一个方法,该方法可以立即返回,然后通过属性更改或信号“返回值”。这可能是一个好主意的具体情况,如Wi扫描调用。
  2. 方法实现:您的API可能有一个在返回之前需要很长时间的方法,并且它可能是“异步地”实现的,因为您的服务没有阻塞,而该方法没有返回--其他方法可以被调用,信号和属性更改也可以在这段时间内发生。可以使用g_dbus_method_invocation_return_*函数来实现这一点。创建长期运行的D-Bus方法并不是一个问题,只要它们是这样的:客户端可以异步地处理调用,如果需要,甚至可以增加默认的方法调用超时。

在您发布的示例代码的上下文中,您需要做的第一件事是使RadioScan()调用异步,或者在另一个线程中执行调用:这将确保您的服务在调用期间保持响应。

在您的RadioScan是异步的之后,实现这两种解决方案都很容易。如果RadioScan()方法有一个明确定义的返回值(而且您不希望在前面返回中间结果),我将选择一个只需更长时间的普通方法调用:

代码语言:javascript
复制
static void handle_method_call(GDBusConnection *conn, ...)
{
    if (!g_strcmp0(method_name, "Scan")) {
        // start the async scan (maybe using another thread): this should 
        // return immediately and call the callback when scan is done
        start_radio_scan(..., radio_scan_finished_cb); 
        // do not return the invocation here, just store a pointer to it          
    }
}

static void radio_scan_finished_cb (...)
{
    // return the D-Bbus method call with the invocation that was stored earlier
    g_dbus_method_invocation_return_value(invocation, ...)
}

如果扫描结果随着时间的推移实际到达(例如,1秒后的第一个结果,3秒后的更多结果),那么在结果可用时将结果作为信号返回可能是有意义的,然后返回方法调用作为扫描最终完成的标志。

拥有一个"ScanFinalResponse“信号当然是可能的,但是我不认为在一个只需要更长时间的方法调用上这样做有什么好处。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45529462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档