为什么采用rpc通信,回调函数注册成功,call函数所发的数据,回调函数能够收到,同时,回调函数内的返回值也是结果,但是为什么回调函数的返回值不管是什么内容,call函数收到的返回值都是其所发的数据,而不是回调函数的返回值,应该怎么解决?
时间: 2024-08-15 13:09:25 浏览: 62
RPC (Remote Procedure Call) 通常用于客户端和服务端之间的交互,它允许远程调用服务并等待响应。当通过回调函数处理RPC请求时,以下情况发生:
1. **数据发送和接收**:`call` 函数发出的数据包含了一个请求,包含了需要调用的服务名以及任何必需的参数。这部分数据并不包含回调函数的返回值。
2. **异步调用**:RPC通常是异步的,即 `call` 函数在发送请求后立即返回,而不会阻塞直到服务器响应。因此,它无法获取回调函数的实际返回值,因为此时这个值还未计算出来。
3. **回调设计**:回调函数的作用是在服务器完成操作后将结果传递给客户端。当你设置回调函数的时候,实际上已经预设了何时及如何接收到服务器的响应。
为了解决这个问题,你需要确保回调函数正确地处理了服务器的响应,并将结果从服务器传回给调用的地方。通常的做法如下:
- **正确解析回调**:确保回调函数内部正确处理返回的结果,并将其存储在一个地方,如全局变量、作用域变量或者作为参数传递给另一个函数。
- **数据封装**:如果你的应用支持,可以考虑改变数据结构,在服务器返回的原始数据中嵌入回调函数的地址,以便于回调时访问正确的返回值。
- **错误处理**:明确区分正常的返回值和异常情况,确保不论何种情况,都能将正确的结果传递回给 `call` 函数。
记住,重要的是要在设计上清晰地分离数据的流动路径,以及什么时候应该期待来自回调的响应,什么时候期望直接从`call`函数获得结果。
相关问题
用c++写一个带有回调函数的rabbitmq订阅者代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <amqp.h>
#include <amqp_framing.h> int main(int argc, char const *argv[])
{
amqp_connection_state_t conn;
int port = 5672;
char const *hostname = "localhost";
char const *exchange;
char const *bindingkey;
char const *queue;
amqp_socket_t *socket = NULL; conn = amqp_new_connection(); socket = amqp_tcp_socket_new(conn);
if (!socket) {
printf("creating socket failed\n");
return -1;
} int status = amqp_socket_open(socket, hostname, port);
if (status) {
printf("opening socket failed\n");
return -1;
} amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"); amqp_channel_open(conn, 1); amqp_exchange_declare(conn, 1, exchange, amqp_cstring_bytes("direct"), 0, 0, 0, 0, amqp_empty_table);
amqp_queue_declare(conn, 1, queue, 0, 0, 0, 0, amqp_empty_table); amqp_queue_bind(conn, 1, queue, exchange, bindingkey, amqp_empty_table); amqp_basic_consume(conn, 1, queue, amqp_empty_bytes, 0, 0, 0, amqp_empty_table,
amqp_basic_consume_callback,
(void *)&callback_data); while (1) {
amqp_rpc_reply_t res;
amqp_envelope_t envelope; amqp_maybe_release_buffers(conn); res = amqp_consume_message(conn, &envelope, NULL, 0); if (AMQP_RESPONSE_NORMAL != res.reply_type) {
break;
} callback_data.message_count++; callback_data.cb(envelope.message.body.bytes, envelope.message.body.len); amqp_destroy_envelope(&envelope);
} amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS);
amqp_connection_close(conn, AMQP_REPLY_SUCCESS);
amqp_destroy_connection(conn);
return 0;
}
如何将自己的函数注册到SPDK的RPC
要将自己的函数注册到SPDK的RPC,需要遵循以下步骤:
1. 创建一个RPC函数,该函数应该遵循SPDK提供的RPC函数的规则。可以参考SPDK提供的示例代码来编写函数。
2. 将该函数添加到一个RPC服务中。可以使用SPDK提供的rpc_register函数来实现。该函数将RPC函数注册到指定的服务中。
3. 将RPC服务添加到RPC服务器中。可以使用SPDK提供的rpc_server_register函数来实现。该函数将RPC服务注册到RPC服务器中。
4. 在SPDK应用程序中启动RPC服务器。可以使用SPDK提供的rpc_server_run函数来实现。该函数将启动RPC服务器并开始监听客户端的连接请求。
以下是示例代码:
```c
#include <stdio.h>
#include "spdk/rpc.h"
static void my_rpc_func(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
// Your code here...
}
static const struct spdk_json_object_decoder my_rpc_func_decoders[] = {
{ "param1", offsetof(struct my_rpc_params, param1), spdk_json_decode_int32 },
{ "param2", offsetof(struct my_rpc_params, param2), spdk_json_decode_string },
SPDK_JSON_OBJECT_DECODER_END
};
static const struct spdk_json_rpc_handler my_rpc_func_handler = {
.method = "my_rpc_func",
.params_schema = spdk_json_schema_build(my_rpc_func_decoders),
.handler = my_rpc_func,
};
static const struct spdk_json_rpc_service my_rpc_service = {
.handlers = { &my_rpc_func_handler, NULL },
.methods = NULL,
};
int main()
{
// Register RPC service
spdk_rpc_register_service(&my_rpc_service);
// Start RPC server
spdk_rpc_server_run(NULL);
return 0;
}
```
这是一个简单的示例,演示了如何将一个RPC函数注册到RPC服务中,并将该服务注册到RPC服务器中。您可以根据自己的需求进行修改和扩展。