The jsonrpc module provides an implementation of the JSON-RPC 2.0 protocol, supporting request/notification/response message interaction patterns, and can be used with custom transport layers (such as TCP, WebSocket).
In scenarios requiring Remote Procedure Calls (RPC), JSON-RPC is a lightweight and easy-to-implement protocol. The jsonrpc module encapsulates message encoding/decoding, request timeout management, asynchronous response, and other mechanisms, allowing developers to focus only on service method implementation.
#include <tbox/jsonrpc/rpc.h> //! RPC core class
#include <tbox/jsonrpc/proto.h> //! Protocol abstract base class
#include <tbox/jsonrpc/types.h> //! Type definitionsusing ServiceCallback = std::function<bool(int int_id, const Json ¶ms, Response &response)>;- Return
true: synchronous response — the function automatically responds based on response after returning - Return
false: asynchronous response — manually respond later viarespondResult/respondError
Proto is the transport layer abstraction of the protocol. Users need to implement the concrete transport method (e.g., based on TcpConnection):
Full example at
examples/jsonrpc/req_rsp/ping/
Rpc rpc(sp_loop, IdType::kInt);
rpc.initialize(proto, 30); //! Timeout 30 seconds
//! Send request, wait for response
rpc.request("ping", Json::object{{"data", "hello"}},
[](const Response &rsp) {
if (rsp.errcode == 0)
LogInfo("result: %s", rsp.result.dump().c_str());
else
LogErr("error: %d, %s", rsp.errcode, rsp.message.c_str());
}
);Full example at
examples/jsonrpc/req_rsp/pong/
Rpc rpc(sp_loop, IdType::kInt);
rpc.initialize(proto, 30);
//! Register service method
rpc.addService("ping",
[](int int_id, const Json ¶ms, Response &response) {
//! Synchronous response
response.errcode = 0;
response.result = Json::object{{"echo", params["data"]}};
return true;
}
);rpc.addService("async_query",
[](int int_id, const Json ¶ms, Response &response) {
//! Asynchronous processing: do not respond immediately, respond later via respondResult
//! Return false to indicate no automatic response
thread_pool.execute(
[int_id, params] { /* background query */ },
[int_id, &rpc] {
rpc.respondResult(int_id, Json::object{{"status", "ok"}});
}
);
return false;
}
);//! Send notification
rpc.notify("event", Json::object{{"type", "alert"}});Full example at
examples/jsonrpc/message/ping/andpong/
Suitable for simple message passing scenarios without the request-response pattern.
- Request-Response: Client sends a request, server responds with a result
- Asynchronous Processing: Server receives a request, processes asynchronously, and responds later
- Event Notification: One side sends a notification message, the other side only receives without responding
- Timeout Management: Requests that exceed the timeout automatically trigger a timeout callback
- ID Type: Int ID auto-increment is simple and efficient; String ID (e.g., UUID) is more secure but has higher overhead
- Proto Implementation: You must implement the Proto's
onRecvData()method yourself to parse transport layer data - Timeout: Requests sent via
requestthat do not receive a response within the timeout period will trigger a timeout callback (errcode != 0) - int_id for Asynchronous Response: When responding asynchronously, you must save the
int_idand use it later to respond - clear() Resets State: Resets the RPC object's cached data, restoring it to a state where no data has been sent or received
- event: Runs based on Loop
- eventx: Uses TimeoutMonitor for request timeout management
- network: Can implement Proto transport layer based on TcpConnection
- base: Provides infrastructure such as Json, Cabinet/Token
