RPC User Services Connection Guide
Overview: During plugin development
- The plugin sdk may not have a special service interface that meets the user's needs. At this point, this interface can be implemented locally, and then the RPC interface can be used to provide services in the
aubo_scopscripting system .- Maybe the user has already completed the interface implementation of various services required locally. If the
aubo_capssystem is used to re-implement it, it will consume a lot of manpower and resources, then use theaubo_scopescripting system to provide the RPC interface to remotely call ouraubo_capsplug-in system outside the implementation of the various types of services.- Note: The port number of the server side of this example is 8988, which is given in the code. If necessary, you can set up the interface so that the user can set the port number, and then read the value set by the user in the corresponding place.
Use of the sample project: package it using the commands in the
README, then refer to https://docs.aubo-robotics.cn/application_notes/07-plugin_load_unload/ to load it into theaubo_scope
Below, the author will demonstrate the whole process by using building two projects, where user_serviceis user service and json_rpc_test is plugin system.
Adjusting the code structure
In the plug-in development process, it is recommended that the user services and plug-in system code is managed separately. This code structure is clear and easy to maintain.
As shown in the figure: link the user service as a sub-project to the plugin system

Create a new folder in the src directory of the plugin system for storing user services.

Write
CMakeLilsts.txtin the user service file to manage the user service code and to facilitate the linking of plug-in systems.
The part commented out here is what needs to be implemented for subsequent use of
json_rpc, and needs to be added here after implementation.
cmakeset(CMAKE_CXX_STANDARD 17) set(CMAKE_VERBOSE_MAKEFILE ON) set(rpc_test_srcs) set(rpc_test_hdrs) set(rpc_test_hpps) file(GLOB_RECURSE rpc_test_srcs "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") file(GLOB_RECURSE rpc_test_hdrs "${CMAKE_CURRENT_SOURCE_DIR}/*.h") file(GLOB_RECURSE rpc_test_hpps "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp") find_package(Thread) # user_service server-side add_executable(user_service # httplib.h # user_service_test.h # user_service_test.cpp # user_service_test_server.h # user_service_test_server.cpp # user_service.h # user_service_test_demon.cpp # cpphttplibconnector.hpp ) target_include_directories(user_service PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) # target_link_libraries(user_service PUBLIC json-rpc-cxx nlohmann_json) target_link_libraries(user_service PRIVATE ${CMAKE_THREAD_LIBS_INIT}) set_target_properties(user_service PROPERTIES OUTPUT_NAME user_service PREFIX "" DEBUG_POSTFIX "" INSTALL_RPATH "$\{ORIGIN\}/lib" ) include_directories("${CMAKE_CURRENT_SOURCE_DIR}")Add the user service as a sub-project to the plugin system (write the following command in
CMakeLists.txtin the plugin system, note the path).
cmakeadd_subdirectory(src/user_service)Re
Cmakethe whole project, and the project structure will be programmed to match the user's desired structure.
-Download and link json-rpc-cxx to your local project.
First write the following command in the CMakeLists.txt file of the plugin system:

CPMAddPackage(json-rpc-cxx1
NAME json-rpc-cxx1
VERSION 0.3.0
GIT_REPOSITORY https://gitee.com/aubo-robotics/json-rpc-cxx.git
EXCLUDE_FROM_ALL YES
OPTIONS
"COMPILE_EXAMPLES OFF"
"COMPILE_TESTS OFF"
)
CPMAddPackage(json1
NAME json1
VERSION 3.9.1
GIT_REPOSITORY https://gitee.com/aubo-robotics/json-v3.9.1.git
EXCLUDE_FROM_ALL YES
OPTIONS
"JSON_BuildTests OFF"
"JSON_Install OFF"
)Because for the time beingthe plugin system json_rpc_testdoes not need to use the json_rpc service, and the json_rpc service is needed in the user service systemuser_service, linking the downloaded packages to the user service system only requires writing the following command in the user service system CMakeLists.txt with the following command:

target_link_libraries(user_service PUBLIC json-rpc-cxx nlohmann_json)user service system
user_serviceinducthttplib.hcpphttplibconnector.hppfile
httplib.h File Link:src/httplib.h cpphttplibconnector.hpp File Link: src/cpphttplibconnector.hpp
Linking these two files to the User Services system requires writing the following command in the User ServicesCMakeLists.txt

httplib.h
cpphttplibconnector.hppIntroducing user services
Here the author customized the
test.habstract class and derived theuser_service.hclass from it, and implemented thetestFunction()interface in theuser_service.hclass to mimic the various types of service interfaces already implemented by users.Here, the author's test case is structured as follows:
Linking test cases to the**user service system
user_service: **
cmakeuser_service.h user_service.cpp test.htest.h:
c++#ifndef TEST_H #define TEST_H #include <string> #include <vector> #include <map> #include <memory> // User Service Abstract Interface, do one implementation for one model class Test { public: virtual ~Test() = default; virtual int testFunction() = 0; }; using TestPtr = std::shared_ptr<Test>; #endif // TEST_Huser_service.h:
c++#ifndef USER_SERVICE_H #define USER_SERVICE_H #include "test.h" class UserService : public Test { public: UserService(); int testFunction() override; }; using UserServicePtr = std::shared_ptr<UserService>; #endif // USER_SERVICE_Huser_service.cpp:
c++#include "user_service.h" UserService::UserService() { } int UserService::testFunction() { int test_result{12345}; return test_result; }Add an rpc service to the test case: (Here, a functional module that enables RPC service needs to be implemented, and users need to add interfaces from their function module to this rpc service)

user_service_rpc_service.hdocument:
c++#ifndef USERSERVICERPCSERVICE_H #define USERSERVICERPCSERVICE_H #include "cpphttplibconnector.hpp" #include "user_service.h" class UserServiceRpcService : public jsonrpccxx::JsonRpc2Server { public: UserServiceRpcService(int port = 8988); ~UserServiceRpcService(); bool startListening(); void join(); private: CppHttpLibServerConnectorPtr connector_; UserServicePtr user_service_; }; #endif // USERSERVICERPCSERVICE_Huser_service_rpc_service.cppdocument:
C++#include "user_service_rpc_service.h" UserServiceRpcService::UserServiceRpcService(int port) { // Set the ip and port number of the server side of the user service system, after this part is done, it will be set in the aubo_scope // Connect to this server in the script connector_ = std::shared_ptr<CppHttpLibServerConnector>( new CppHttpLibServerConnector(*this, port)); // Instantiate a UserService ,for use in placing UserService // Add the required interfaces inside to this rpc service user_service_ = std::make_shared<UserService>(); // Services provided by UserService Add("testFunction", jsonrpccxx::GetHandle(&UserService::testFunction, *user_service_), {}); } UserServiceRpcService::~UserServiceRpcService() { } bool UserServiceRpcService::startListening() { std::cout << "start startListening" << std::endl; connector_->StartListening(); } void UserServiceRpcService::join() { connector_->join(); }Starting the user service as a server
Here, since the add_deecutable command was written in the cmakeLists.txt file to generate the user_Service executable program, simply starting the executable program will start the user_Service as the server. There are two ways to start it: manually starting the file or starting it in the plugin system.
The idea of starting this file in the plugin system: start this server as soon as the user enters the plugin system. The specific implementation is as follows:
Because the function of connecting external devices to the aubo_stope plugin system is located on the installation node, the server can be started by enabling external programs in the installation node program.
- First, add an external program interface to the installation node:

- Package the generated server-side file (generated user service system executable file) into the plug-in system zip file to facilitate the plug-in system to start the file.
CMakeinstall(TARGETS user_service DESTINATION .)Effect: Packaging the plugin will add a
user_serviceexecutable under arcs_ws/estensions/json_rpc_test/.
- Finally, start the program in the plugin system
json_rpc_testinstallation node:
Reads the set
user_servicepath:(1) Pass the project path into the installation node in the activation function

(2) Save the
aubo_capsworking path to theserviceclass

(3) Pass the
aubo_capsworking path into thenodenode for ease of use

When installing the node construct, start the user server program:
c++user_server_ = new QProcess(); // FIXME: Finding the correct load path auto dir = QDir(location.c_str()); dir.cd(".."); user_server_->setProgram(QString("%1/user_service").arg(dir.path())); user_server_->setArguments(QStringList() << QString::number(8988)); QObject::connect(user_server_, &QProcess::stateChanged, [](QProcess::ProcessState newState) { // }); QObject::connect(user_server_, &QProcess::errorOccurred, [](QProcess::ProcessError error) { // }); // Starting the user server user_server_->start();Connect the plugin to the user service server
Write the connection script in the plugin system installation node:
C++// Connecting to the server script_writer->appendLine( QString( "local api = sched.jsonrpc.proxy('http://127.0.0.1:%1/jsonrpc')") .arg(8988) .toStdString());Add the required services (interfaces) on the user service server side
C++// Services provided by UserService Add("testFunction", jsonrpccxx::GetHandle(&UserService::testFunction, *user_service_), {});Using services (interfaces) that have been added to the server in aubo_scope scripts
C++// Testing calls to external interfaces script_writer->appendLine("local result = api.testFunction()"); script_writer->appendLine( "print(1111111111111111111111111111111111111111111111)"); // Printing the obtained results script_writer->appendLine("print(result)");