The code requires cc_generic_services = true in the service proto files. nng_msg payload is: request format : size:u32 + serialized MethodCall response format: size:u32 + serialized MethodCallResponse Dispatch is done using descriptors, message prototypes and protobuf.Any. Error handling is missing apart from error logging.
93 lines
2.4 KiB
C++
93 lines
2.4 KiB
C++
#include <atomic>
|
|
#include <memory>
|
|
|
|
#include <mesytec-mvlc/mesytec-mvlc.h>
|
|
#include <mesytec-mvlc/util/signal_handling.h>
|
|
#include "proto/service.pb.h"
|
|
#include <mesytec-mnode/mnode_nng_async.h>
|
|
|
|
using namespace mesytec;
|
|
using namespace mesytec::mnode;
|
|
using namespace std::literals;
|
|
|
|
class PingClient: public nng::AsyncReqWork
|
|
{
|
|
public:
|
|
explicit PingClient(nng_socket socket)
|
|
: AsyncReqWork(socket)
|
|
{
|
|
}
|
|
|
|
nng::unique_msg make_request() override
|
|
{
|
|
ping_.set_peer_id(peer_id);
|
|
ping_.set_sequence_number(sequence_number++);
|
|
return nng::make_message(ping_.SerializeAsString());
|
|
}
|
|
|
|
void handle_reply(nng::unique_msg &&request, nng::unique_msg &&reply) override
|
|
{
|
|
ping_.ParseFromArray(nng_msg_body(request.get()), nng_msg_len(request.get()));
|
|
pong_.ParseFromArray(nng_msg_body(reply.get()), nng_msg_len(reply.get()));
|
|
|
|
if (ping_.sequence_number() != pong_.sequence_number())
|
|
spdlog::error("Work: sequence_number mismatch: ping={}, pong={}",
|
|
ping_.sequence_number(), pong_.sequence_number());
|
|
|
|
if (ping_.peer_id() != pong_.peer_id())
|
|
spdlog::error("Work: peer_id mismatch: ping={}, pong={}", ping_.peer_id(),
|
|
pong_.peer_id());
|
|
|
|
++num_transactions;
|
|
}
|
|
|
|
void report()
|
|
{
|
|
spdlog::info("PingClient, peer_id={}, transactions={}", peer_id, num_transactions);
|
|
}
|
|
|
|
private:
|
|
proto::Ping ping_;
|
|
proto::Pong pong_;
|
|
size_t sequence_number = 1;
|
|
static std::atomic<size_t> next_peer_id;
|
|
size_t peer_id = next_peer_id++;
|
|
size_t num_transactions = 0;
|
|
};
|
|
|
|
std::atomic<size_t> PingClient::next_peer_id;
|
|
|
|
int main()
|
|
{
|
|
spdlog::set_level(spdlog::level::info);
|
|
|
|
auto socket = nng::make_req_socket(1000);
|
|
|
|
if (int res = nng_dial(socket, "tcp://localhost:5555", nullptr, NNG_FLAG_NONBLOCK))
|
|
{
|
|
nng::mnode_nng_error("nng_dial", res);
|
|
return res;
|
|
}
|
|
|
|
mvlc::util::Stopwatch sw;
|
|
std::vector<std::unique_ptr<PingClient>> clients;
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
clients.emplace_back(std::make_unique<PingClient>(socket));
|
|
|
|
for (auto &client: clients)
|
|
client->work();
|
|
|
|
for (;;)
|
|
{
|
|
nng_msleep(100);
|
|
if (sw.get_interval() >= 1s)
|
|
{
|
|
for (auto &client: clients)
|
|
client->report();
|
|
sw.interval();
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|