feat update rpc_core
This commit is contained in:
parent
b412e7e11c
commit
a3ba7c6045
@ -1,5 +0,0 @@
|
||||
Language: Cpp
|
||||
BasedOnStyle: Google
|
||||
ColumnLimit: 150
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortLambdasOnASingleLine: Empty
|
29
3party/rpc_core/.github/workflows/build.yml
vendored
29
3party/rpc_core/.github/workflows/build.yml
vendored
@ -1,29 +0,0 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
jobs:
|
||||
Linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -DRPC_CORE_TEST_PLUGIN=ON ..
|
||||
|
||||
- name: Init thirdparty
|
||||
run: cd build && make rpc_core_test_init
|
||||
|
||||
- name: Build
|
||||
run: cd build && make -j2
|
||||
|
||||
- name: Run
|
||||
run: cd build && ./rpc_core_test
|
14
3party/rpc_core/.gitignore
vendored
14
3party/rpc_core/.gitignore
vendored
@ -1,14 +0,0 @@
|
||||
build/
|
||||
|
||||
# clion
|
||||
.idea/
|
||||
cmake-build-*/
|
||||
|
||||
# qt creator
|
||||
CMakeLists.txt.user
|
||||
|
||||
# vscode
|
||||
.vscode/
|
||||
|
||||
# thirdparty
|
||||
/thirdparty/
|
@ -2,13 +2,18 @@ cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(rpc_core CXX)
|
||||
|
||||
# config
|
||||
option(RPC_CORE_SERIALIZE_USE_CUSTOM "" "")
|
||||
option(RPC_CORE_SERIALIZE_USE_NLOHMANN_JSON "" ON)
|
||||
|
||||
# test
|
||||
option(RPC_CORE_BUILD_TEST "" OFF)
|
||||
option(RPC_CORE_TEST_PLUGIN "" OFF)
|
||||
option(RPC_CORE_TEST_LINK_PTHREAD "" OFF)
|
||||
|
||||
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(RPC_CORE_BUILD_TEST ON)
|
||||
endif ()
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(RPC_CORE_BUILD_TEST ON)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
add_compile_options(-Wall -Wunused-parameter)
|
||||
@ -16,39 +21,54 @@ add_compile_options(-Wall -Wunused-parameter)
|
||||
add_library(${PROJECT_NAME} INTERFACE)
|
||||
target_include_directories(${PROJECT_NAME} INTERFACE include)
|
||||
|
||||
if (RPC_CORE_BUILD_TEST)
|
||||
set(EXAMPLE_COMPILE_DEFINE
|
||||
ANDROID_STANDALONE
|
||||
RPC_CORE_LOG_SHOW_DEBUG
|
||||
# RPC_CORE_LOG_SHOW_VERBOSE
|
||||
)
|
||||
if(RPC_CORE_SERIALIZE_USE_CUSTOM)
|
||||
target_compile_definitions(
|
||||
${PROJECT_NAME}
|
||||
INTERFACE -DRPC_CORE_SERIALIZE_USE_CUSTOM="${RPC_CORE_SERIALIZE_USE_CUSTOM}"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(TARGET_NAME ${PROJECT_NAME}_test)
|
||||
file(GLOB SRCS test/main.cpp test/test_rpc.cpp test/test_serialize.cpp test/test_data_packer.cpp)
|
||||
add_executable(${TARGET_NAME})
|
||||
if (RPC_CORE_TEST_LINK_PTHREAD)
|
||||
# some linux platform need link -pthread for std::future api
|
||||
set(LIBRARIES -pthread)
|
||||
endif ()
|
||||
target_link_libraries(${TARGET_NAME} ${PROJECT_NAME} ${LIBRARIES})
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE ${EXAMPLE_COMPILE_DEFINE})
|
||||
if(RPC_CORE_SERIALIZE_USE_NLOHMANN_JSON)
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
INTERFACE -DRPC_CORE_SERIALIZE_USE_NLOHMANN_JSON)
|
||||
endif()
|
||||
|
||||
if (RPC_CORE_TEST_PLUGIN)
|
||||
list(APPEND SRCS test/test_plugin.cpp)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE "RPC_CORE_TEST_PLUGIN")
|
||||
add_custom_target(${TARGET_NAME}_init
|
||||
# clear dir
|
||||
COMMAND rm -rf ${CMAKE_CURRENT_LIST_DIR}/thirdparty
|
||||
# json
|
||||
COMMAND mkdir -p ${CMAKE_CURRENT_LIST_DIR}/thirdparty/nlohmann
|
||||
COMMAND curl -L -o ${CMAKE_CURRENT_LIST_DIR}/thirdparty/nlohmann/json.hpp https://github.com/nlohmann/json/releases/download/v3.11.2/json.hpp
|
||||
# flatbuffers
|
||||
COMMAND git clone https://github.com/google/flatbuffers.git --depth=1 --branch=v23.1.21 ${CMAKE_CURRENT_LIST_DIR}/thirdparty/flatbuffers
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
if(RPC_CORE_BUILD_TEST)
|
||||
set(EXAMPLE_COMPILE_DEFINE ANDROID_STANDALONE RPC_CORE_LOG_SHOW_DEBUG
|
||||
# RPC_CORE_LOG_SHOW_VERBOSE
|
||||
)
|
||||
|
||||
target_include_directories(${TARGET_NAME} PRIVATE thirdparty)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE thirdparty/flatbuffers/include)
|
||||
endif ()
|
||||
target_sources(${TARGET_NAME} PRIVATE ${SRCS})
|
||||
endif ()
|
||||
set(TARGET_NAME ${PROJECT_NAME}_test)
|
||||
file(GLOB SRCS test/main.cpp test/test_rpc.cpp test/test_serialize.cpp
|
||||
test/test_data_packer.cpp)
|
||||
add_executable(${TARGET_NAME})
|
||||
if(RPC_CORE_TEST_LINK_PTHREAD)
|
||||
# some linux platform need link -pthread for std::future api
|
||||
set(LIBRARIES -pthread)
|
||||
endif()
|
||||
target_link_libraries(${TARGET_NAME} ${PROJECT_NAME} ${LIBRARIES})
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE ${EXAMPLE_COMPILE_DEFINE})
|
||||
|
||||
if(RPC_CORE_TEST_PLUGIN)
|
||||
list(APPEND SRCS test/test_plugin.cpp)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE "RPC_CORE_TEST_PLUGIN")
|
||||
add_custom_target(
|
||||
${TARGET_NAME}_init
|
||||
# clear dir
|
||||
COMMAND rm -rf ${CMAKE_CURRENT_LIST_DIR}/thirdparty
|
||||
# json
|
||||
COMMAND mkdir -p ${CMAKE_CURRENT_LIST_DIR}/thirdparty/nlohmann
|
||||
COMMAND
|
||||
curl -L -o ${CMAKE_CURRENT_LIST_DIR}/thirdparty/nlohmann/json.hpp
|
||||
https://github.com/nlohmann/json/releases/download/v3.11.2/json.hpp
|
||||
# flatbuffers
|
||||
COMMAND git clone https://github.com/google/flatbuffers.git --depth=1
|
||||
--branch=v23.1.21 ${CMAKE_CURRENT_LIST_DIR}/thirdparty/flatbuffers
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
target_include_directories(${TARGET_NAME} PRIVATE thirdparty)
|
||||
target_include_directories(${TARGET_NAME}
|
||||
PRIVATE thirdparty/flatbuffers/include)
|
||||
endif()
|
||||
target_sources(${TARGET_NAME} PRIVATE ${SRCS})
|
||||
endif()
|
||||
|
21
3party/rpc_core/LICENSE
Normal file
21
3party/rpc_core/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023-2024 liushuai
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,6 +1,7 @@
|
||||
# rpc_core
|
||||
|
||||
[![Build Status](https://github.com/shuai132/rpc_core/workflows/build/badge.svg)](https://github.com/shuai132/rpc_core/actions?workflow=build)
|
||||
[![Build Status](https://github.com/shuai132/rpc_core/workflows/cpp/badge.svg)](https://github.com/shuai132/rpc_core/actions?workflow=cpp)
|
||||
[![Build Status](https://github.com/shuai132/rpc_core/workflows/rust/badge.svg)](https://github.com/shuai132/rpc_core/actions?workflow=rust)
|
||||
|
||||
a tiny c++11 rpc library, supports all platforms (macOS, Linux, Windows, iOS, Android, etc.) and most microchips (
|
||||
Arduino, STM32, ESP32/ESP8266, etc.)
|
||||
@ -30,6 +31,14 @@ For TCP-based implementations: [asio_net](https://github.com/shuai132/asio_net)
|
||||
* Timeout and Retry API
|
||||
* Support `std::future` interface
|
||||
|
||||
## Language supports
|
||||
|
||||
* C++
|
||||
- [asio_net](https://github.com/shuai132/asio_net): based on [asio](https://think-async.com/Asio/#)
|
||||
|
||||
* Rust
|
||||
- [./rust](./rust): based on [tokio](https://github.com/tokio-rs/tokio)
|
||||
|
||||
## Requirements
|
||||
|
||||
* C++11
|
||||
@ -139,6 +148,10 @@ json: `{"id":1,"age":18,"name":"test"}`
|
||||
* [json.hpp](include/rpc_core/plugin/json.hpp)
|
||||
A flexible way to use `nlohmann/json`
|
||||
|
||||
# License
|
||||
|
||||
This project is licensed under the [MIT license](LICENSE).
|
||||
|
||||
## Links
|
||||
|
||||
* Implementation based on asio: [asio_net](https://github.com/shuai132/asio_net)
|
||||
|
@ -43,10 +43,18 @@ struct default_connection : connection {
|
||||
* Loopback connection for testing
|
||||
*/
|
||||
struct loopback_connection : public connection {
|
||||
loopback_connection() {
|
||||
send_package_impl = [this](std::string payload) {
|
||||
on_recv_package(std::move(payload));
|
||||
static std::pair<std::shared_ptr<connection>, std::shared_ptr<connection>> create() {
|
||||
auto c1 = std::make_shared<connection>();
|
||||
auto c1_weak = std::weak_ptr<connection>(c1);
|
||||
auto c2 = std::make_shared<connection>();
|
||||
auto c2_weak = std::weak_ptr<connection>(c2);
|
||||
c1->send_package_impl = [c2_weak](std::string package) {
|
||||
c2_weak.lock()->on_recv_package(std::move(package));
|
||||
};
|
||||
c2->send_package_impl = [c1_weak](std::string package) {
|
||||
c1_weak.lock()->on_recv_package(std::move(package));
|
||||
};
|
||||
return std::make_pair(c1, c2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
namespace rpc_core {
|
||||
namespace detail {
|
||||
|
||||
class msg_dispatcher : noncopyable {
|
||||
class msg_dispatcher : public std::enable_shared_from_this<msg_dispatcher>, noncopyable {
|
||||
public:
|
||||
using cmd_handle = std::function<std::pair<bool, msg_wrapper>(msg_wrapper)>;
|
||||
using rsp_handle = std::function<bool(msg_wrapper)>;
|
||||
@ -21,17 +21,20 @@ class msg_dispatcher : noncopyable {
|
||||
using timer_impl = std::function<void(uint32_t ms, timeout_cb)>;
|
||||
|
||||
public:
|
||||
explicit msg_dispatcher(std::shared_ptr<connection> conn) : conn_(std::move(conn)) {
|
||||
auto alive = std::weak_ptr<void>(is_alive_);
|
||||
conn_->on_recv_package = ([this, RPC_CORE_MOVE_LAMBDA(alive)](const std::string& payload) {
|
||||
if (alive.expired()) {
|
||||
explicit msg_dispatcher(std::shared_ptr<connection> conn) : conn_(std::move(conn)) {}
|
||||
|
||||
void init() {
|
||||
auto self = std::weak_ptr<msg_dispatcher>(shared_from_this());
|
||||
conn_->on_recv_package = ([RPC_CORE_MOVE_LAMBDA(self)](const std::string& payload) {
|
||||
auto self_lock = self.lock();
|
||||
if (!self_lock) {
|
||||
RPC_CORE_LOGD("msg_dispatcher expired");
|
||||
return;
|
||||
}
|
||||
bool success;
|
||||
auto msg = coder::deserialize(payload, success);
|
||||
if (success) {
|
||||
this->dispatch(std::move(msg));
|
||||
self_lock->dispatch(std::move(msg));
|
||||
} else {
|
||||
RPC_CORE_LOGE("payload deserialize error");
|
||||
}
|
||||
@ -70,21 +73,18 @@ class msg_dispatcher : noncopyable {
|
||||
}
|
||||
const auto& fn = it->second;
|
||||
const bool need_rsp = msg.type & msg_wrapper::need_rsp;
|
||||
auto resp = fn(msg);
|
||||
auto resp = fn(std::move(msg));
|
||||
if (need_rsp && resp.first) {
|
||||
RPC_CORE_LOGD("=> seq:%u type:rsp", msg.seq);
|
||||
RPC_CORE_LOGD("=> seq:%u type:rsp", resp.second.seq);
|
||||
conn_->send_package_impl(coder::serialize(resp.second));
|
||||
}
|
||||
} break;
|
||||
|
||||
case msg_wrapper::response: {
|
||||
// pong or response
|
||||
const bool isPong = msg.type & msg_wrapper::pong;
|
||||
const auto handleMap = isPong ? &pong_handle_map_ : &rsp_handle_map_;
|
||||
|
||||
RPC_CORE_LOGD("<= seq:%u type:%s", msg.seq, (msg.type & detail::msg_wrapper::msg_type::pong) ? "pong" : "rsp");
|
||||
auto it = handleMap->find(msg.seq);
|
||||
if (it == handleMap->cend()) {
|
||||
auto it = rsp_handle_map_.find(msg.seq);
|
||||
if (it == rsp_handle_map_.cend()) {
|
||||
RPC_CORE_LOGD("no rsp for seq:%u", msg.seq);
|
||||
break;
|
||||
}
|
||||
@ -94,11 +94,11 @@ class msg_dispatcher : noncopyable {
|
||||
return;
|
||||
}
|
||||
if (cb(std::move(msg))) {
|
||||
handleMap->erase(it);
|
||||
RPC_CORE_LOGV("handleMap->size=%zu", handleMap->size());
|
||||
RPC_CORE_LOGV("rsp_handle_map_.size=%zu", rsp_handle_map_.size());
|
||||
} else {
|
||||
RPC_CORE_LOGE("may deserialize error");
|
||||
}
|
||||
rsp_handle_map_.erase(it);
|
||||
} break;
|
||||
|
||||
default:
|
||||
@ -122,31 +122,30 @@ class msg_dispatcher : noncopyable {
|
||||
}
|
||||
}
|
||||
|
||||
void subscribe_rsp(seq_type seq, rsp_handle handle, RPC_CORE_MOVE_PARAM(timeout_cb) timeout_cb, uint32_t timeout_ms, bool is_ping) {
|
||||
void subscribe_rsp(seq_type seq, rsp_handle handle, RPC_CORE_MOVE_PARAM(timeout_cb) timeout_cb, uint32_t timeout_ms) {
|
||||
RPC_CORE_LOGD("subscribe_rsp seq:%u", seq);
|
||||
if (handle == nullptr) return;
|
||||
const auto handleMap = is_ping ? &pong_handle_map_ : &rsp_handle_map_;
|
||||
|
||||
(*handleMap)[seq] = std::move(handle);
|
||||
|
||||
if (timer_impl_ == nullptr) {
|
||||
RPC_CORE_LOGW("no timeout will cause memory leak!");
|
||||
return;
|
||||
}
|
||||
|
||||
auto alive = std::weak_ptr<void>(is_alive_);
|
||||
timer_impl_(timeout_ms, [handleMap, seq, RPC_CORE_MOVE_LAMBDA(timeout_cb), RPC_CORE_MOVE_LAMBDA(alive)] {
|
||||
if (alive.expired()) {
|
||||
rsp_handle_map_[seq] = std::move(handle);
|
||||
auto self = std::weak_ptr<msg_dispatcher>(shared_from_this());
|
||||
timer_impl_(timeout_ms, [RPC_CORE_MOVE_LAMBDA(self), seq, RPC_CORE_MOVE_LAMBDA(timeout_cb)] {
|
||||
auto self_lock = self.lock();
|
||||
if (!self_lock) {
|
||||
RPC_CORE_LOGD("seq:%u timeout after destroy", seq);
|
||||
return;
|
||||
}
|
||||
auto it = handleMap->find(seq);
|
||||
if (it != handleMap->cend()) {
|
||||
auto it = self_lock->rsp_handle_map_.find(seq);
|
||||
if (it != self_lock->rsp_handle_map_.cend()) {
|
||||
if (timeout_cb) {
|
||||
timeout_cb();
|
||||
}
|
||||
handleMap->erase(seq);
|
||||
RPC_CORE_LOGV("Timeout seq=%d, handleMap.size=%zu", seq, handleMap->size());
|
||||
self_lock->rsp_handle_map_.erase(seq);
|
||||
RPC_CORE_LOGV("Timeout seq=%d, rsp_handle_map_.size=%zu", seq, this->rsp_handle_map_.size());
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -159,9 +158,7 @@ class msg_dispatcher : noncopyable {
|
||||
std::shared_ptr<connection> conn_;
|
||||
std::map<cmd_type, cmd_handle> cmd_handle_map_;
|
||||
std::map<seq_type, rsp_handle> rsp_handle_map_;
|
||||
std::map<seq_type, rsp_handle> pong_handle_map_;
|
||||
timer_impl timer_impl_;
|
||||
std::shared_ptr<void> is_alive_ = std::make_shared<uint8_t>();
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
@ -25,7 +25,7 @@ struct msg_wrapper : copyable { // NOLINT
|
||||
cmd_type cmd;
|
||||
msg_type type;
|
||||
std::string data;
|
||||
std::string* request_payload = nullptr;
|
||||
std::string const* request_payload = nullptr;
|
||||
|
||||
std::string dump() const {
|
||||
char tmp[100];
|
||||
|
@ -29,7 +29,7 @@ class request : detail::noncopyable, public std::enable_shared_from_this<request
|
||||
struct rpc_proto {
|
||||
virtual ~rpc_proto() = default;
|
||||
virtual seq_type make_seq() = 0;
|
||||
virtual void send_request(const request_s&) = 0;
|
||||
virtual void send_request(request const*) = 0;
|
||||
virtual bool is_ready() const = 0;
|
||||
};
|
||||
using send_proto_s = std::shared_ptr<rpc_proto>;
|
||||
@ -80,7 +80,7 @@ class request : detail::noncopyable, public std::enable_shared_from_this<request
|
||||
auto r = std::shared_ptr<request>(new request(std::forward<Args>(args)...), [](request* p) {
|
||||
delete p;
|
||||
});
|
||||
r->init();
|
||||
r->timeout(nullptr);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ class request : detail::noncopyable, public std::enable_shared_from_this<request
|
||||
return;
|
||||
}
|
||||
seq_ = r->make_seq();
|
||||
r->send_request(self_keeper_);
|
||||
r->send_request(this);
|
||||
if (!need_rsp_) {
|
||||
on_finish(finally_t::no_need_rsp);
|
||||
}
|
||||
@ -268,7 +268,7 @@ class request : detail::noncopyable, public std::enable_shared_from_this<request
|
||||
return rpc_;
|
||||
}
|
||||
|
||||
bool canceled() const {
|
||||
bool is_canceled() const {
|
||||
return canceled_;
|
||||
}
|
||||
|
||||
@ -301,10 +301,6 @@ class request : detail::noncopyable, public std::enable_shared_from_this<request
|
||||
}
|
||||
|
||||
private:
|
||||
void init() {
|
||||
timeout(nullptr);
|
||||
}
|
||||
|
||||
void on_finish(finally_t type) {
|
||||
if (!waiting_rsp_) return;
|
||||
waiting_rsp_ = false;
|
||||
|
@ -28,7 +28,9 @@ class rpc : detail::noncopyable, public std::enable_shared_from_this<rpc>, publi
|
||||
}
|
||||
|
||||
private:
|
||||
explicit rpc(std::shared_ptr<connection> conn = std::make_shared<default_connection>()) : conn_(conn), dispatcher_(std::move(conn)) {
|
||||
explicit rpc(std::shared_ptr<connection> conn = std::make_shared<default_connection>())
|
||||
: conn_(conn), dispatcher_(std::make_shared<detail::msg_dispatcher>(std::move(conn))) {
|
||||
dispatcher_->init();
|
||||
RPC_CORE_LOGD("rpc: %p", this);
|
||||
}
|
||||
|
||||
@ -42,7 +44,7 @@ class rpc : detail::noncopyable, public std::enable_shared_from_this<rpc>, publi
|
||||
}
|
||||
|
||||
inline void set_timer(detail::msg_dispatcher::timer_impl timer_impl) {
|
||||
dispatcher_.set_timer_impl(std::move(timer_impl));
|
||||
dispatcher_->set_timer_impl(std::move(timer_impl));
|
||||
}
|
||||
|
||||
inline void set_ready(bool ready) {
|
||||
@ -54,11 +56,11 @@ class rpc : detail::noncopyable, public std::enable_shared_from_this<rpc>, publi
|
||||
void subscribe(const cmd_type& cmd, RPC_CORE_MOVE_PARAM(F) handle) {
|
||||
constexpr bool F_ReturnIsEmpty = std::is_void<typename detail::callable_traits<F>::return_type>::value;
|
||||
constexpr bool F_ParamIsEmpty = detail::callable_traits<F>::argc == 0;
|
||||
subscribe_helper<F, F_ReturnIsEmpty, F_ParamIsEmpty>()(cmd, std::move(handle), &dispatcher_);
|
||||
subscribe_helper<F, F_ReturnIsEmpty, F_ParamIsEmpty>()(cmd, std::move(handle), dispatcher_.get());
|
||||
}
|
||||
|
||||
inline void unsubscribe(const cmd_type& cmd) {
|
||||
dispatcher_.unsubscribe_cmd(cmd);
|
||||
dispatcher_->unsubscribe_cmd(cmd);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -79,9 +81,9 @@ class rpc : detail::noncopyable, public std::enable_shared_from_this<rpc>, publi
|
||||
return seq_++;
|
||||
}
|
||||
|
||||
void send_request(const request_s& request) override {
|
||||
void send_request(request const* request) override {
|
||||
if (request->need_rsp_) {
|
||||
dispatcher_.subscribe_rsp(request->seq_, request->rsp_handle_, request->timeout_cb_, request->timeout_ms_, request->is_ping_);
|
||||
dispatcher_->subscribe_rsp(request->seq_, request->rsp_handle_, request->timeout_cb_, request->timeout_ms_);
|
||||
}
|
||||
detail::msg_wrapper msg;
|
||||
msg.type = static_cast<detail::msg_wrapper::msg_type>(detail::msg_wrapper::command | (request->is_ping_ ? detail::msg_wrapper::ping : 0) |
|
||||
@ -157,7 +159,7 @@ class rpc : detail::noncopyable, public std::enable_shared_from_this<rpc>, publi
|
||||
|
||||
private:
|
||||
std::shared_ptr<connection> conn_;
|
||||
detail::msg_dispatcher dispatcher_;
|
||||
std::shared_ptr<detail::msg_dispatcher> dispatcher_;
|
||||
seq_type seq_{0};
|
||||
bool is_ready_ = false;
|
||||
};
|
||||
|
@ -3,6 +3,16 @@
|
||||
// config
|
||||
#include "config.hpp"
|
||||
|
||||
#if defined(RPC_CORE_SERIALIZE_USE_CUSTOM)
|
||||
|
||||
#include RPC_CORE_SERIALIZE_USE_CUSTOM
|
||||
|
||||
#elif defined(RPC_CORE_SERIALIZE_USE_NLOHMANN_JSON)
|
||||
|
||||
#include "serialize_nlohmann_json.hpp"
|
||||
|
||||
#else
|
||||
|
||||
// type traits
|
||||
#include "detail/type_traits.hpp"
|
||||
|
||||
@ -32,3 +42,5 @@
|
||||
#include "serialize/type_ptr.hpp"
|
||||
#include "serialize/type_struct.hpp"
|
||||
#include "serialize/type_void.hpp"
|
||||
|
||||
#endif
|
||||
|
25
3party/rpc_core/include/rpc_core/serialize_nlohmann_json.hpp
Normal file
25
3party/rpc_core/include/rpc_core/serialize_nlohmann_json.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "detail/log.h"
|
||||
#include "detail/string_view.hpp"
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
namespace rpc_core {
|
||||
|
||||
template <typename T>
|
||||
inline std::string serialize(T&& t) {
|
||||
return nlohmann::json(t).dump(-1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool deserialize(const detail::string_view& data, T& t) {
|
||||
try {
|
||||
t = nlohmann::json::parse(data.data(), data.data() + data.size()).get<T>();
|
||||
return true;
|
||||
} catch (std::exception& e) {
|
||||
RPC_CORE_LOGE("deserialize: %s", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rpc_core
|
@ -2,7 +2,7 @@
|
||||
|
||||
#define RPC_CORE_VER_MAJOR 2
|
||||
#define RPC_CORE_VER_MINOR 0
|
||||
#define RPC_CORE_VER_PATCH 1
|
||||
#define RPC_CORE_VER_PATCH 2
|
||||
|
||||
#define RPC_CORE_TO_VERSION(major, minor, patch) (major * 10000 + minor * 100 + patch)
|
||||
#define RPC_CORE_VERSION RPC_CORE_TO_VERSION(RPC_CORE_VER_MAJOR, RPC_CORE_VER_MINOR, RPC_CORE_VER_PATCH)
|
||||
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "rpc_core",
|
||||
"description": "a tiny c++11 rpc library, supports all platforms (macOS, Linux, Windows, iOS, Android, etc.) and most microchips (Arduino, STM32, ESP32/ESP8266, etc.)",
|
||||
"keywords": "rpc",
|
||||
"authors": {
|
||||
"name": "shuai132",
|
||||
"maintainer": true
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/shuai132/rpc_core.git"
|
||||
},
|
||||
"version": "2.0.1",
|
||||
"build": {
|
||||
"srcDir": "_",
|
||||
"flags": [
|
||||
"-I include"
|
||||
]
|
||||
}
|
||||
}
|
@ -190,6 +190,7 @@ if(SLED_BUILD_TESTS)
|
||||
sled_add_test(NAME sled_symbolize_test SRCS
|
||||
src/sled/debugging/symbolize_test.cc NO_MAIN)
|
||||
sled_add_test(NAME sled_sigslot_test SRCS src/sled/sigslot_test.cc)
|
||||
sled_add_test(NAME sled_rpc_test SRCS src/sled/network/rpc_test.cc)
|
||||
endif(SLED_BUILD_TESTS)
|
||||
|
||||
if(SLED_BUILD_FUZZ)
|
||||
|
@ -10,6 +10,8 @@
|
||||
#define SLED_THREAD_ANNOTATION_ATTRIBUTE__(x)// no-op
|
||||
#endif
|
||||
|
||||
#define SLED_UNUSED(x) (void) (x)
|
||||
|
||||
#define SLED_CAPABILITY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
|
||||
|
||||
#define SLED_SCOPED_CAPABILITY SLED_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
|
||||
|
6
src/sled/network/rpc.h
Normal file
6
src/sled/network/rpc.h
Normal file
@ -0,0 +1,6 @@
|
||||
#include <rpc_core.hpp>
|
||||
#include <rpc_core/serialize.hpp>
|
||||
|
||||
namespace sled {
|
||||
using namespace rpc_core;
|
||||
}// namespace sled
|
33
src/sled/network/rpc_test.cc
Normal file
33
src/sled/network/rpc_test.cc
Normal file
@ -0,0 +1,33 @@
|
||||
#include <sled/lang/attributes.h>
|
||||
#include <sled/network/rpc.h>
|
||||
#include <sled/random.h>
|
||||
#include <sled/time_utils.h>
|
||||
|
||||
TEST_SUITE("RPC")
|
||||
{
|
||||
TEST_CASE("loopback")
|
||||
{
|
||||
auto conn = sled::loopback_connection::create();
|
||||
auto rpc_client = sled::rpc::create(conn.first);
|
||||
auto rpc_server = sled::rpc::create(conn.second);
|
||||
rpc_server->set_timer([](uint32_t ms, const sled::rpc::timeout_cb &cb) {
|
||||
SLED_UNUSED(ms);
|
||||
SLED_UNUSED(cb);
|
||||
});
|
||||
rpc_client->set_timer([](uint32_t ms, const sled::rpc::timeout_cb &cb) {
|
||||
SLED_UNUSED(ms);
|
||||
SLED_UNUSED(cb);
|
||||
});
|
||||
rpc_server->set_ready(true);
|
||||
rpc_client->set_ready(true);
|
||||
sled::Random rand(sled::TimeUTCMicros());
|
||||
|
||||
rpc_server->subscribe("cmd", [](int x) { return x + 1; });
|
||||
|
||||
int random_value = rand.Rand(0, 10000);
|
||||
rpc_client->cmd("cmd")
|
||||
->msg(random_value)
|
||||
->rsp([random_value](int x) { CHECK_EQ(x, random_value + 1); })
|
||||
->call();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user