Skip to content

Commit 21c8d0b

Browse files
dkroenkeelBoberido
authored andcommitted
iox-#27 Add Client/Server example
Signed-off-by: Dietrich Krönke <[email protected]>
1 parent 9a92f9a commit 21c8d0b

9 files changed

+717
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# SPDX-License-Identifier: Apache-2.0
16+
17+
# Build request_response_basic example
18+
cmake_minimum_required(VERSION 3.16)
19+
project(example_request_response)
20+
21+
include(GNUInstallDirs)
22+
23+
find_package(iceoryx_posh REQUIRED)
24+
find_package(iceoryx_hoofs REQUIRED)
25+
26+
get_target_property(ICEORYX_CXX_STANDARD iceoryx_posh::iceoryx_posh CXX_STANDARD)
27+
include(IceoryxPlatform)
28+
29+
## C++ untyped API client
30+
add_executable(
31+
iox-cpp-request-response-untyped-client
32+
client_cxx_untyped.cpp
33+
)
34+
target_link_libraries(
35+
iox-cpp-request-response-untyped-client
36+
PRIVATE
37+
iceoryx_hoofs::iceoryx_hoofs
38+
iceoryx_posh::iceoryx_posh
39+
)
40+
target_compile_options(
41+
iox-cpp-request-response-untyped-client
42+
PRIVATE
43+
${ICEORYX_WARNINGS}
44+
${ICEORYX_SANITIZER_FLAGS}
45+
)
46+
47+
## C++ typed API server
48+
add_executable(
49+
iox-cpp-request-response-untyped-server
50+
server_cxx_untpyed.cpp
51+
)
52+
target_link_libraries(
53+
iox-cpp-request-response-untyped-server
54+
PRIVATE
55+
iceoryx_hoofs::iceoryx_hoofs
56+
iceoryx_posh::iceoryx_posh
57+
)
58+
target_compile_options(
59+
iox-cpp-request-response-untyped-server
60+
PRIVATE
61+
${ICEORYX_WARNINGS}
62+
${ICEORYX_SANITIZER_FLAGS}
63+
)
64+
65+
## C++ typed API client
66+
add_executable(
67+
iox-cpp-request-response-basic-client
68+
client_cxx_basic.cpp
69+
)
70+
target_link_libraries(
71+
iox-cpp-request-response-basic-client
72+
PRIVATE
73+
iceoryx_hoofs::iceoryx_hoofs
74+
iceoryx_posh::iceoryx_posh
75+
)
76+
target_compile_options(
77+
iox-cpp-request-response-basic-client
78+
PRIVATE
79+
${ICEORYX_WARNINGS}
80+
${ICEORYX_SANITIZER_FLAGS}
81+
)
82+
83+
## C++ typed API client with events
84+
add_executable(
85+
iox-cpp-request-response-event-client
86+
client_cxx_listener.cpp
87+
)
88+
target_link_libraries(
89+
iox-cpp-request-response-event-client
90+
PRIVATE
91+
iceoryx_hoofs::iceoryx_hoofs
92+
iceoryx_posh::iceoryx_posh
93+
)
94+
target_compile_options(
95+
iox-cpp-request-response-event-client
96+
PRIVATE
97+
${ICEORYX_WARNINGS}
98+
${ICEORYX_SANITIZER_FLAGS}
99+
)
100+
101+
## C++ typed API server
102+
add_executable(
103+
iox-cpp-request-response-basic-server
104+
server_cxx_basic.cpp
105+
)
106+
target_link_libraries(
107+
iox-cpp-request-response-basic-server
108+
PRIVATE
109+
iceoryx_hoofs::iceoryx_hoofs
110+
iceoryx_posh::iceoryx_posh
111+
)
112+
target_compile_options(
113+
iox-cpp-request-response-basic-server
114+
PRIVATE
115+
${ICEORYX_WARNINGS}
116+
${ICEORYX_SANITIZER_FLAGS}
117+
)
118+
119+
## C++ typed API server with events
120+
add_executable(
121+
iox-cpp-request-response-listener-server
122+
server_cxx_listener.cpp
123+
)
124+
target_link_libraries(
125+
iox-cpp-request-response-listener-server
126+
PRIVATE
127+
iceoryx_hoofs::iceoryx_hoofs
128+
iceoryx_posh::iceoryx_posh
129+
)
130+
target_compile_options(
131+
iox-cpp-request-response-listener-server
132+
PRIVATE
133+
${ICEORYX_WARNINGS}
134+
${ICEORYX_SANITIZER_FLAGS}
135+
)
136+
137+
## additional properties
138+
set_target_properties(
139+
iox-cpp-request-response-untyped-client
140+
iox-cpp-request-response-untyped-server
141+
iox-cpp-request-response-basic-client
142+
iox-cpp-request-response-basic-server
143+
iox-cpp-request-response-event-client
144+
iox-cpp-request-response-listener-server
145+
PROPERTIES
146+
CXX_STANDARD_REQUIRED ON
147+
CXX_STANDARD ${ICEORYX_CXX_STANDARD}
148+
POSITION_INDEPENDENT_CODE ON
149+
)
150+
151+
install(
152+
TARGETS
153+
iox-cpp-request-response-untyped-client
154+
iox-cpp-request-response-untyped-server
155+
iox-cpp-request-response-basic-client
156+
iox-cpp-request-response-basic-server
157+
iox-cpp-request-response-event-client
158+
iox-cpp-request-response-listener-server
159+
RUNTIME DESTINATION bin
160+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
//! [iceoryx includes]
18+
#include "request_and_response_types.hpp"
19+
20+
#include "iceoryx_hoofs/posix_wrapper/signal_watcher.hpp"
21+
#include "iceoryx_posh/popo/client.hpp"
22+
#include "iceoryx_posh/runtime/posh_runtime.hpp"
23+
//! [iceoryx includes]
24+
25+
#include <iostream>
26+
27+
int main()
28+
{
29+
//! [initialize runtime]
30+
constexpr char APP_NAME[] = "iox-cpp-request-response-client-basic";
31+
iox::runtime::PoshRuntime::initRuntime(APP_NAME);
32+
//! [initialize runtime]
33+
34+
//! [create client]
35+
iox::popo::Client<AddRequest, AddResponse> client({"Example", "Request-Response", "Add"});
36+
//! [create client]
37+
38+
//! [send requests in a loop]
39+
uint64_t fibonacciLast = 0;
40+
uint64_t fibonacciCurrent = 1;
41+
int64_t requestSequenceId = 0;
42+
int64_t expectedResponseSequenceId = requestSequenceId;
43+
while (!iox::posix::hasTerminationRequested())
44+
{
45+
//! [send request]
46+
client.loan()
47+
.and_then([&](auto& request) {
48+
request.getRequestHeader().setSequenceId(requestSequenceId);
49+
expectedResponseSequenceId = requestSequenceId;
50+
requestSequenceId += 1;
51+
request->augend = fibonacciLast;
52+
request->addend = fibonacciCurrent;
53+
std::cout << APP_NAME << " Send Request: " << fibonacciLast << " + " << fibonacciCurrent << std::endl;
54+
request.send();
55+
})
56+
.or_else([](auto& error) {
57+
std::cout << "Could not allocate Request! Return value = " << static_cast<uint64_t>(error) << std::endl;
58+
});
59+
//! [send request]
60+
61+
// the server polls with an interval of 100ms
62+
constexpr std::chrono::milliseconds DELAY_TIME{150U};
63+
std::this_thread::sleep_for(DELAY_TIME);
64+
65+
//! [take response]
66+
while (client.take().and_then([&](const auto& response) {
67+
auto receivedSequenceId = response.getResponseHeader().getSequenceId();
68+
if (receivedSequenceId == expectedResponseSequenceId)
69+
{
70+
fibonacciLast = fibonacciCurrent;
71+
fibonacciCurrent = response->sum;
72+
std::cout << APP_NAME << " Got Response : " << fibonacciCurrent << std::endl;
73+
}
74+
else
75+
{
76+
std::cout << "Got Response with outdated sequence ID! Expected = " << expectedResponseSequenceId
77+
<< "; Actual = " << receivedSequenceId << "! -> skip" << std::endl;
78+
}
79+
}))
80+
{
81+
};
82+
//! [take response]
83+
84+
constexpr std::chrono::milliseconds SLEEP_TIME{950U};
85+
std::this_thread::sleep_for(SLEEP_TIME);
86+
}
87+
//! [send requests in a loop]
88+
89+
return EXIT_SUCCESS;
90+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
//! [iceoryx includes]
18+
#include "request_and_response_types.hpp"
19+
20+
#include "iceoryx_hoofs/internal/concurrent/smart_lock.hpp"
21+
#include "iceoryx_hoofs/posix_wrapper/signal_watcher.hpp"
22+
#include "iceoryx_posh/popo/client.hpp"
23+
#include "iceoryx_posh/popo/listener.hpp"
24+
#include "iceoryx_posh/popo/notification_callback.hpp"
25+
#include "iceoryx_posh/runtime/posh_runtime.hpp"
26+
//! [iceoryx includes]
27+
28+
#include <iostream>
29+
30+
constexpr char APP_NAME[] = "iox-cpp-request-response-client-listener";
31+
32+
struct ContextData
33+
{
34+
uint64_t fibonacciLast = 0;
35+
uint64_t fibonacciCurrent = 1;
36+
int64_t requestSequenceId = 0;
37+
int64_t expectedResponseSequenceId = requestSequenceId;
38+
};
39+
40+
void onResponseReceived(iox::popo::Client<AddRequest, AddResponse>* client,
41+
iox::concurrent::smart_lock<ContextData>* ctx)
42+
{
43+
auto guardedCtx = ctx->getScopeGuard();
44+
//! [take response]
45+
while (client->take().and_then([&](const auto& response) {
46+
auto receivedSequenceId = response.getResponseHeader().getSequenceId();
47+
if (receivedSequenceId == guardedCtx->expectedResponseSequenceId)
48+
{
49+
guardedCtx->fibonacciLast = guardedCtx->fibonacciCurrent;
50+
guardedCtx->fibonacciCurrent = response->sum;
51+
std::cout << APP_NAME << " Got Response : " << guardedCtx->fibonacciCurrent << std::endl;
52+
}
53+
else
54+
{
55+
std::cout << "Got Response with outdated sequence ID! Expected = " << guardedCtx->expectedResponseSequenceId
56+
<< "; Actual = " << receivedSequenceId << "! -> skip" << std::endl;
57+
}
58+
}))
59+
{
60+
}
61+
//! [take response]
62+
}
63+
64+
int main()
65+
{
66+
//! [initialize runtime]
67+
constexpr char APP_NAME[] = "iox-cpp-request-response-client-listener";
68+
iox::runtime::PoshRuntime::initRuntime(APP_NAME);
69+
//! [initialize runtime]
70+
71+
iox::popo::Listener listener;
72+
73+
//! [create client]
74+
iox::popo::Client<AddRequest, AddResponse> client({"Example", "Request-Response", "Add"});
75+
//! [create client]
76+
77+
iox::concurrent::smart_lock<ContextData> ctx;
78+
79+
listener
80+
.attachEvent(client,
81+
iox::popo::ClientEvent::RESPONSE_RECEIVED,
82+
iox::popo::createNotificationCallback(onResponseReceived, ctx))
83+
.or_else([](auto) {
84+
std::cerr << "unable to attach server" << std::endl;
85+
std::exit(EXIT_FAILURE);
86+
});
87+
88+
//! [send requests in a loop]
89+
while (!iox::posix::hasTerminationRequested())
90+
{
91+
//! [send request]
92+
client.loan()
93+
.and_then([&](auto& request) {
94+
auto guardedCtx = ctx.getScopeGuard();
95+
request.getRequestHeader().setSequenceId(guardedCtx->requestSequenceId);
96+
guardedCtx->expectedResponseSequenceId = guardedCtx->requestSequenceId;
97+
guardedCtx->requestSequenceId += 1;
98+
request->augend = guardedCtx->fibonacciLast;
99+
request->addend = guardedCtx->fibonacciCurrent;
100+
std::cout << APP_NAME << " Send Request: " << guardedCtx->fibonacciLast << " + "
101+
<< guardedCtx->fibonacciCurrent << std::endl;
102+
request.send();
103+
})
104+
.or_else([](auto& error) {
105+
std::cout << "Could not allocate Request! Return value = " << static_cast<uint64_t>(error) << std::endl;
106+
});
107+
//! [send request]
108+
109+
constexpr std::chrono::milliseconds SLEEP_TIME{1000U};
110+
std::this_thread::sleep_for(SLEEP_TIME);
111+
}
112+
//! [send requests in a loop]
113+
114+
listener.detachEvent(client, iox::popo::ClientEvent::RESPONSE_RECEIVED);
115+
116+
return EXIT_SUCCESS;
117+
}

0 commit comments

Comments
 (0)