It is possible to monitor messages sent to a thrift service by using the portmonitor carrier.
Using thrift client
With YARP, it is possible to generate a Monitor
class that can be used to inspect which messages are sent to the service, by passing the yarp.monitor = "true"
annotation. For example, suppose we have the following structure in service.thrift
service Demo
{
i32 get_answer();
bool set_answer(1:i32 rightAnswer)
}
that is used to produce a static library
cmake_minimum_required(VERSION 3.19)
project(thriftEditor_example)
# Needed to link the static library from the plugin, on 64 bit
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
find_package(YARP COMPONENTS os idl_tools REQUIRED)
add_library(demo_protocol STATIC)
yarp_idl_to_dir(
INPUT_FILES Demo.thrift
OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/demo
SOURCES_VAR IDL_GEN_SRCS
HEADERS_VAR IDL_GEN_HDRS
INCLUDE_DIRS_VAR IDL_INCLUDE_DIRS
PLACEMENT MERGED
)
target_sources(demo_protocol
PRIVATE
${IDL_GEN_SRCS}
${IDL_GEN_HDRS}
)
target_include_directories(demo_protocol
PUBLIC
$<BUILD_INTERFACE:${IDL_INCLUDE_DIRS}>
)
target_link_libraries(demo_protocol
PRIVATE
YARP::YARP_os)
a server
class DemoServer :
public Demo
{
int32_t mAnswer {42};
public:
int32_t get_answer() override { return mAnswer; }
bool set_answer(int32_t rightAnswer) override { mAnswer = rightAnswer; return true; }
};
int main(int argc, char* argv[])
{
DemoServer demoServer;
demoServer.yarp().attachAsServer(port);
if (!port.
open(
"/demo/server")) {
return 1;
}
while (true) {
yDebug() <<
"Demo server running happily";
}
return 0;
}
Utilities for manipulating the YARP network, including initialization and shutdown.
A port that is specialized as an RPC server.
void delay(double seconds)
Wait for a certain number of seconds.
The main, catch-all namespace for YARP.
add_executable(demo_server)
target_sources(demo_server PRIVATE DemoServer.cpp)
target_link_libraries(demo_server
PRIVATE
YARP::YARP_os
YARP::YARP_init
demo_protocol
)
and a client
int main(int argc, char* argv[])
{
client_port.
open(
"/demo/client");
if (!
yarp.connect(
"/demo/client",
"/demo/server",
"tcp")) {
yError() <<
"Could not connect to server /demo/server";
return -1;
}
Demo demo;
demo.yarp().attachAsClient(client_port);
int32_t answer = demo.get_answer();
demo.set_answer(answer + 4);
answer = demo.get_answer();
return 0;
}
A port that is specialized as an RPC client.
add_executable(demo_client)
target_sources(demo_client PRIVATE DemoClient.cpp)
target_link_libraries(demo_client
PRIVATE
YARP::YARP_os
YARP::YARP_init
demo_protocol
)
It is possible to enable the generation of the FakeService::Monitor
class in this way:
service Demo
{
i32 get_answer();
bool set_answer(1:i32 rightAnswer)
} (
yarp.monitor = "true"
)
yarp_prepare_plugin(demo_monitor
TYPE Demo::Monitor
INCLUDE ${IDL_GEN_HDRS} # FIXME there should be a way to get this automatically
CATEGORY portmonitor
INTERNAL ON
)
yarp_add_plugin(demo_monitor)
target_link_libraries(demo_monitor
PRIVATE
YARP::YARP_os
demo_protocol
)
yarp_install(
TARGETS demo_monitor
EXPORT demo_monitor
COMPONENT demo_monitor
LIBRARY DESTINATION ${YARP_DYNAMIC_PLUGINS_INSTALL_DIR}
ARCHIVE DESTINATION ${YARP_STATIC_PLUGINS_INSTALL_DIR}
YARP_INI DESTINATION ${YARP_PLUGIN_MANIFESTS_INSTALL_DIR}
)
It is then possible to modify the connection in the client to use the new portmonitor
if (!
yarp.connect(
"/demo/client",
"/demo/server",
"tcp++send.portmonitor+type.dll+file.demo_monitor")) {
In this way, the client will send a message to the /monitor
port for every command sent or reply received. The name of the monitor port can be changed by passing +monitor.<monitor port>
option to the carrier, for example
if (!
yarp.connect(
"/demo/client",
"/demo/server",
"tcp++send.portmonitor+type.dll+file.demo_monitor+monitor./demo/monitor")) {
Using yarp rpc or custom clients
The same thing can be done also running yarp rpc
in client mode. This is usually useless, but it can be helpful for debugging. Also the same method can be used if the client is written manually, and not using thrift,
yarp rpc --client /demo/yarprpc
and connecting it in a different terminal, using the right connection argument:
yarp connect /demo/yarprpc /demo/server tcp+send.portmonitor+type.dll+file.demo_monitor
If enabled, in order to monitor a connection using yarp rpc
, it is also possible to use the generic version of the portmonitor (this does not work with thrift clients, but only with yarp rpc
or other clients using yarp::os::Bottle and yarp::os::CommandBottle):
yarp connect /demo/yarprpc /demo/server tcp+send.portmonitor+type.dll+file.rpc_monitor