Skip to content

Commit

Permalink
iox-#27 Add Client/Server example
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Feb 15, 2022
1 parent 95536c7 commit 08f6def
Show file tree
Hide file tree
Showing 9 changed files with 713 additions and 0 deletions.
160 changes: 160 additions & 0 deletions iceoryx_examples/request_response_basic/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

# Build request_response_basic example
cmake_minimum_required(VERSION 3.5)
project(example_request_response_basic)

include(GNUInstallDirs)

find_package(iceoryx_posh REQUIRED)
find_package(iceoryx_hoofs REQUIRED)

get_target_property(ICEORYX_CXX_STANDARD iceoryx_posh::iceoryx_posh CXX_STANDARD)
include(IceoryxPlatform)

## C++ untyped API client
add_executable(
iox-cpp-request-response-untyped-client
client_untyped_cxx_api.cpp
)
target_link_libraries(
iox-cpp-request-response-untyped-client
PRIVATE
iceoryx_hoofs::iceoryx_hoofs
iceoryx_posh::iceoryx_posh
)
target_compile_options(
iox-cpp-request-response-untyped-client
PRIVATE
${ICEORYX_WARNINGS}
${ICEORYX_SANITIZER_FLAGS}
)

## C++ typed API server
add_executable(
iox-cpp-request-response-untyped-server
server_untyped_cxx_api.cpp
)
target_link_libraries(
iox-cpp-request-response-untyped-server
PRIVATE
iceoryx_hoofs::iceoryx_hoofs
iceoryx_posh::iceoryx_posh
)
target_compile_options(
iox-cpp-request-response-untyped-server
PRIVATE
${ICEORYX_WARNINGS}
${ICEORYX_SANITIZER_FLAGS}
)

## C++ typed API client
add_executable(
iox-cpp-request-response-basic-client
client_cxx_api.cpp
)
target_link_libraries(
iox-cpp-request-response-basic-client
PRIVATE
iceoryx_hoofs::iceoryx_hoofs
iceoryx_posh::iceoryx_posh
)
target_compile_options(
iox-cpp-request-response-basic-client
PRIVATE
${ICEORYX_WARNINGS}
${ICEORYX_SANITIZER_FLAGS}
)

## C++ typed API client with events
add_executable(
iox-cpp-request-response-event-client
client_cxx_api_event.cpp
)
target_link_libraries(
iox-cpp-request-response-event-client
PRIVATE
iceoryx_hoofs::iceoryx_hoofs
iceoryx_posh::iceoryx_posh
)
target_compile_options(
iox-cpp-request-response-event-client
PRIVATE
${ICEORYX_WARNINGS}
${ICEORYX_SANITIZER_FLAGS}
)

## C++ typed API server
add_executable(
iox-cpp-request-response-basic-server
server_cxx_api.cpp
)
target_link_libraries(
iox-cpp-request-response-basic-server
PRIVATE
iceoryx_hoofs::iceoryx_hoofs
iceoryx_posh::iceoryx_posh
)
target_compile_options(
iox-cpp-request-response-basic-server
PRIVATE
${ICEORYX_WARNINGS}
${ICEORYX_SANITIZER_FLAGS}
)

## C++ typed API server with events
add_executable(
iox-cpp-request-response-event-server
server_cxx_api_event.cpp
)
target_link_libraries(
iox-cpp-request-response-event-server
PRIVATE
iceoryx_hoofs::iceoryx_hoofs
iceoryx_posh::iceoryx_posh
)
target_compile_options(
iox-cpp-request-response-event-server
PRIVATE
${ICEORYX_WARNINGS}
${ICEORYX_SANITIZER_FLAGS}
)

## additional properties
set_target_properties(
iox-cpp-request-response-untyped-client
iox-cpp-request-response-untyped-server
iox-cpp-request-response-basic-client
iox-cpp-request-response-basic-server
iox-cpp-request-response-event-client
iox-cpp-request-response-event-server
PROPERTIES
CXX_STANDARD_REQUIRED ON
CXX_STANDARD ${ICEORYX_CXX_STANDARD}
POSITION_INDEPENDENT_CODE ON
)

install(
TARGETS
iox-cpp-request-response-untyped-client
iox-cpp-request-response-untyped-server
iox-cpp-request-response-basic-client
iox-cpp-request-response-basic-server
iox-cpp-request-response-event-client
iox-cpp-request-response-event-server
RUNTIME DESTINATION bin
)
90 changes: 90 additions & 0 deletions iceoryx_examples/request_response_basic/client_cxx_api.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

//! [iceoryx includes]
#include "request_and_response_types.hpp"

#include "iceoryx_hoofs/posix_wrapper/signal_watcher.hpp"
#include "iceoryx_posh/popo/client.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"
//! [iceoryx includes]

#include <iostream>

int main()
{
//! [initialize runtime]
constexpr char APP_NAME[] = "iox-cpp-request-response-client";
iox::runtime::PoshRuntime::initRuntime(APP_NAME);
//! [initialize runtime]

//! [create client]
iox::popo::Client<AddRequest, AddResponse> client({"Example", "Request-Response", "Add"});
//! [create client]

//! [send requests in a loop]
uint64_t fibonacciLast = 0;
uint64_t fibonacciCurrent = 1;
int64_t requestSequenceId = 0;
int64_t expectedResponseSequenceId = requestSequenceId;
while (!iox::posix::hasTerminationRequested())
{
//! [send request]
client.loan()
.and_then([&](auto& request) {
request.getRequestHeader().setSequenceId(requestSequenceId);
expectedResponseSequenceId = requestSequenceId;
requestSequenceId += 1;
request->augend = fibonacciLast;
request->addend = fibonacciCurrent;
std::cout << "Send Request: " << fibonacciLast << " + " << fibonacciCurrent << std::endl;
request.send();
})
.or_else([](auto& error) {
std::cout << "Could not allocate Request! Return value = " << static_cast<uint64_t>(error) << std::endl;
});
//! [send request]

// the server polls with an interval of 100ms
constexpr std::chrono::milliseconds DELAY_TIME{150U};
std::this_thread::sleep_for(DELAY_TIME);

//! [take response]
while (client.take().and_then([&](const auto& response) {
auto receivedSequenceId = response.getResponseHeader().getSequenceId();
if (receivedSequenceId == expectedResponseSequenceId)
{
fibonacciLast = fibonacciCurrent;
fibonacciCurrent = response->sum;
std::cout << "Got Response : " << fibonacciCurrent << std::endl;
}
else
{
std::cout << "Got Response with outdated sequence ID! Expected = " << expectedResponseSequenceId
<< "; Actual = " << receivedSequenceId << "! -> skip" << std::endl;
}
}))
{
};
//! [take response]

constexpr std::chrono::milliseconds SLEEP_TIME{950U};
std::this_thread::sleep_for(SLEEP_TIME);
}
//! [send requests in a loop]

return EXIT_SUCCESS;
}
115 changes: 115 additions & 0 deletions iceoryx_examples/request_response_basic/client_cxx_api_event.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

//! [iceoryx includes]
#include "request_and_response_types.hpp"

#include "iceoryx_hoofs/internal/concurrent/smart_lock.hpp"
#include "iceoryx_hoofs/posix_wrapper/signal_watcher.hpp"
#include "iceoryx_posh/popo/client.hpp"
#include "iceoryx_posh/popo/listener.hpp"
#include "iceoryx_posh/popo/notification_callback.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"
//! [iceoryx includes]

#include <iostream>

struct ContextData
{
uint64_t fibonacciLast = 0;
uint64_t fibonacciCurrent = 1;
int64_t requestSequenceId = 0;
int64_t expectedResponseSequenceId = requestSequenceId;
};

void onResponseReceived(iox::popo::Client<AddRequest, AddResponse>* client,
iox::concurrent::smart_lock<ContextData>* ctx)
{
auto guardedCtx = ctx->getScopeGuard();
//! [take response]
while (client->take().and_then([&](const auto& response) {
auto receivedSequenceId = response.getResponseHeader().getSequenceId();
if (receivedSequenceId == guardedCtx->expectedResponseSequenceId)
{
guardedCtx->fibonacciLast = guardedCtx->fibonacciCurrent;
guardedCtx->fibonacciCurrent = response->sum;
std::cout << "Got Response : " << guardedCtx->fibonacciCurrent << std::endl;
}
else
{
std::cout << "Got Response with outdated sequence ID! Expected = " << guardedCtx->expectedResponseSequenceId
<< "; Actual = " << receivedSequenceId << "! -> skip" << std::endl;
}
}))
{
}
//! [take response]
}

int main()
{
//! [initialize runtime]
constexpr char APP_NAME[] = "iox-cpp-request-response-client-event";
iox::runtime::PoshRuntime::initRuntime(APP_NAME);
//! [initialize runtime]

iox::popo::Listener listener;

//! [create client]
iox::popo::Client<AddRequest, AddResponse> client({"Example", "Request-Response", "Add"});
//! [create client]

iox::concurrent::smart_lock<ContextData> ctx;

listener
.attachEvent(client,
iox::popo::ClientEvent::RESPONSE_RECEIVED,
iox::popo::createNotificationCallback(onResponseReceived, ctx))
.or_else([](auto) {
std::cerr << "unable to attach server" << std::endl;
std::exit(EXIT_FAILURE);
});

//! [send requests in a loop]
while (!iox::posix::hasTerminationRequested())
{
//! [send request]
client.loan()
.and_then([&](auto& request) {
auto guardedCtx = ctx.getScopeGuard();
request.getRequestHeader().setSequenceId(guardedCtx->requestSequenceId);
guardedCtx->expectedResponseSequenceId = guardedCtx->requestSequenceId;
guardedCtx->requestSequenceId += 1;
request->augend = guardedCtx->fibonacciLast;
request->addend = guardedCtx->fibonacciCurrent;
std::cout << "Send Request: " << guardedCtx->fibonacciLast << " + " << guardedCtx->fibonacciCurrent
<< std::endl;
request.send();
})
.or_else([](auto& error) {
std::cout << "Could not allocate Request! Return value = " << static_cast<uint64_t>(error) << std::endl;
});
//! [send request]

constexpr std::chrono::milliseconds SLEEP_TIME{1000U};
std::this_thread::sleep_for(SLEEP_TIME);
}
//! [send requests in a loop]

listener.detachEvent(client, iox::popo::ClientEvent::RESPONSE_RECEIVED);

return EXIT_SUCCESS;
}
Loading

0 comments on commit 08f6def

Please sign in to comment.