Skip to content

Commit cf287be

Browse files
authored
Merge pull request #14 from StephanKa/feature/protobuf-and-cppzmq
Example for usage of protobuf and cppzmq
2 parents 506e15f + 2f32b55 commit cf287be

8 files changed

Lines changed: 165 additions & 1 deletion

File tree

.github/workflows/build_cmake.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
# We need to source the profile file to make sure conan is in PATH
6666
run: |
6767
source ~/.profile
68-
cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCPP_STARTER_USE_SML=ON -DCPP_STARTER_USE_BOOST_BEAST=ON -DCPP_STARTER_USE_CROW=ON
68+
cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCPP_STARTER_USE_SML=ON -DCPP_STARTER_USE_BOOST_BEAST=ON -DCPP_STARTER_USE_CROW=ON -DCPP_STARTER_USE_CPPZMQ_PROTO=ON
6969
7070
- name: Build
7171
working-directory: ${{runner.workspace}}/build

cmake/Conan.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ macro(run_conan)
1919
nlohmann_json/3.10.5
2020
boost/1.78.0
2121
crowcpp-crow/1.0+1
22+
cppzmq/4.8.1
23+
protobuf/3.20.0
2224
OPTIONS
2325
${CONAN_EXTRA_OPTIONS}
2426
gtest:build_gmock=True

src/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
OPTION(CPP_STARTER_USE_SML "Enable compilation of SML sample" OFF)
22
OPTION(CPP_STARTER_USE_BOOST_BEAST "Enable compilation of boost beast sample" OFF)
33
OPTION(CPP_STARTER_USE_CROW "Enable compilation of crow sample" OFF)
4+
OPTION(CPP_STARTER_USE_CPPZMQ_PROTO "Enable compilation of protobuf and cppzmq sample" OFF)
45

56
# SML
67
IF(CPP_STARTER_USE_SML)
@@ -20,6 +21,11 @@ IF(CPP_STARTER_USE_CROW)
2021
ADD_SUBDIRECTORY(crow)
2122
ENDIF()
2223

24+
# CPPZMQ & Protobuf
25+
IF(CPP_STARTER_USE_CPPZMQ_PROTO)
26+
MESSAGE("Using CPPZMQ & Protobuf")
27+
ADD_SUBDIRECTORY(protobuf.cppzmq)
28+
ENDIF()
2329

2430
# Generic test that uses conan libs
2531
ADD_EXECUTABLE(intro main.cpp)

src/protobuf.cppzmq/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FIND_PACKAGE(Protobuf REQUIRED)
2+
3+
INCLUDE_DIRECTORIES(${Protobuf_INCLUDE_DIRS})
4+
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
5+
6+
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${PROTO_SRC_DIR} proto/event.proto)
7+
8+
ADD_EXECUTABLE(test_cppzmq_proto_server server/main.cpp ${PROTO_SRCS} ${PROTO_HDRS})
9+
ADD_EXECUTABLE(test_cppzmq_proto_client client/main.cpp ${PROTO_SRCS} ${PROTO_HDRS})
10+
11+
TARGET_INCLUDE_DIRECTORIES(test_cppzmq_proto_server PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/common)
12+
TARGET_INCLUDE_DIRECTORIES(test_cppzmq_proto_client PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/common)
13+
14+
TARGET_LINK_LIBRARIES(test_cppzmq_proto_server PRIVATE CONAN_PKG::spdlog CONAN_PKG::cppzmq CONAN_PKG::protobuf CONAN_PKG::spdlog)
15+
TARGET_LINK_LIBRARIES(test_cppzmq_proto_client PRIVATE CONAN_PKG::spdlog CONAN_PKG::cppzmq CONAN_PKG::protobuf CONAN_PKG::spdlog)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "event.pb.h"
2+
#include <include/common.h>
3+
#include <spdlog/spdlog.h>
4+
#include <string>
5+
#include <zmq.hpp>
6+
7+
int main()
8+
{
9+
// initialize the zmq context with a single IO thread
10+
zmq::context_t context{ 1 };
11+
12+
// construct a REQ (request) socket and connect to interface
13+
zmq::socket_t socket{ context, zmq::socket_type::req };
14+
socket.connect("tcp://127.0.0.1:5555");
15+
16+
// set up some static data to send
17+
const std::string senderName{ "Client" };
18+
19+
zmq::message_t request{};
20+
// send the request message
21+
auto [sendEvent, serializedData] = Common::prepareMessage(senderName, request);
22+
23+
for (;;) {
24+
// send to the server
25+
socket.send(zmq::buffer(serializedData), zmq::send_flags::none);
26+
27+
// wait for reply from server
28+
socket.recv(request, zmq::recv_flags::none);
29+
const auto [receivedEvent, _] = Common::prepareMessage(senderName, request);
30+
serializedData = Common::incrementPingPong(sendEvent, own::proto::Event::PONG);
31+
sendEvent = receivedEvent;
32+
Common::logProtoEvent(receivedEvent);
33+
34+
if (receivedEvent.pong_count() == Common::maxCount) { break; }
35+
}
36+
37+
return 0;
38+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <spdlog/spdlog.h>
2+
#include <zmq.hpp>
3+
4+
namespace Common {
5+
constexpr auto maxCount = 10;
6+
7+
std::tuple<own::proto::Event, std::string> prepareMessage(const std::string &senderName, const zmq::message_t &request)
8+
{
9+
own::proto::Event receivedEvent{};
10+
std::string data;
11+
receivedEvent.ParseFromArray(request.data(), static_cast<int>(request.size()));
12+
13+
own::proto::Event event{};
14+
event.set_sender(senderName);
15+
event.SerializeToString(&data);
16+
return std::make_tuple(receivedEvent, data);
17+
}
18+
19+
[[nodiscard]]std::string incrementPingPong(own::proto::Event& event, own::proto::Event_PingPong eventType)
20+
{
21+
switch (eventType) {
22+
case own::proto::Event::PING: {
23+
event.set_action(own::proto::Event::PING);
24+
event.set_ping_count(event.ping_count() + 1);
25+
event.set_pong_count(event.pong_count());
26+
}
27+
case own::proto::Event::PONG: {
28+
event.set_action(own::proto::Event::PONG);
29+
event.set_ping_count(event.ping_count());
30+
event.set_pong_count(event.pong_count() + 1);
31+
break;
32+
}
33+
default: {
34+
break;
35+
}
36+
}
37+
std::string data;
38+
event.SerializeToString(&data);
39+
return data;
40+
}
41+
42+
void logProtoEvent(const own::proto::Event &receivedEvent)
43+
{
44+
spdlog::info("Received from: {} - Action: {} - Ping count: {} - Pong count: {}",
45+
receivedEvent.sender(),
46+
own::proto::Event_PingPong_Name(receivedEvent.action()),
47+
receivedEvent.ping_count(),
48+
receivedEvent.pong_count());
49+
}
50+
}// namespace Common
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
syntax = "proto3";
2+
3+
package own.proto;
4+
5+
message Event {
6+
enum PingPong {
7+
PING = 0;
8+
PONG = 1;
9+
}
10+
11+
string sender = 1;
12+
PingPong action = 2;
13+
int32 ping_count = 3;
14+
int32 pong_count = 4;
15+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "event.pb.h"
2+
#include <chrono>
3+
#include <include/common.h>
4+
#include <thread>
5+
6+
int main()
7+
{
8+
using namespace std::chrono_literals;
9+
10+
// initialize the zmq context with a single IO thread
11+
zmq::context_t context{ 1 };
12+
13+
// construct a REP (reply) socket and bind to interface
14+
zmq::socket_t socket{ context, zmq::socket_type::rep };
15+
socket.bind("tcp://*:5555");
16+
17+
// prepare some static data for responses
18+
const std::string senderName{ "Server" };
19+
20+
zmq::message_t request{};
21+
for (;;) {
22+
// receive a request from client
23+
socket.recv(request, zmq::recv_flags::none);
24+
// simulate work
25+
std::this_thread::sleep_for(500ms);
26+
27+
auto [receivedEvent, serializedData] = Common::prepareMessage(senderName, request);
28+
serializedData = Common::incrementPingPong(receivedEvent, own::proto::Event::PING);
29+
Common::logProtoEvent(receivedEvent);
30+
31+
// send the reply to the client
32+
socket.send(zmq::buffer(serializedData), zmq::send_flags::none);
33+
34+
if (receivedEvent.ping_count() == Common::maxCount) { break; }
35+
}
36+
37+
return 0;
38+
}

0 commit comments

Comments
 (0)