This commit is contained in:
Timur A. Fatkhullin 2024-06-11 00:45:50 +03:00
parent 1f9615a6ba
commit 8b2e8fcaaa
5 changed files with 147 additions and 2 deletions

View File

@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.14)
project(ADC LANGUAGES CXX)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# set(CMAKE_BUILD_TYPE Release)
@ -32,7 +34,22 @@ set(ADC_NETWORK_HEADERS
)
option(SPDLOG_LIBRARY "Use SPDLOG library for logging" ON)
option(ASIO_LIBRARY "Use of ASIO library for networking implementation" ON)
if (ASIO_LIBRARY)
find_package(ASIO REQUIRED)
set(ADC_NETWORK_HEADERS ${ADC_NETWORK_HEADERS}
net/adc_netservice_asio.h
)
add_compile_options(ASIO::ASIO)
add_compile_definitions(PUBLIC USE_ASIO_LIBRARY)
endif()
option(SPDLOG_LIBRARY "Use of SPDLOG library for logging" ON)
if (SPDLOG_LIBRARY)
find_package(spdlog REQUIRED)

24
FindASIO.cmake Normal file
View File

@ -0,0 +1,24 @@
#
# ASIO
#
set(ASIO_FOUND FALSE)
find_package(Threads REQUIRED)
find_path(ASIO_DIR asio.hpp HINTS ${ASIO_INSTALL_DIR} PATH_SUFFIXES include)
if (NOT ASIO_DIR)
message(FATAL_ERROR "Cannot find ASIO library headers!")
endif()
message(STATUS "Found ASIO: TRUE (${ASIO_DIR})")
# ASIO is header-only library so it is IMPORTED target
add_library(ASIO::ASIO INTERFACE IMPORTED GLOBAL)
# set standalone version (do not use Boost)
set_target_properties(ASIO::ASIO PROPERTIES INTERFACE_COMPILE_DEFINITIONS "ASIO_STANDALONE" INTERFACE_INCLUDE_DIRECTORIES "${ASIO_DIR}")
target_link_libraries(ASIO::ASIO INTERFACE Threads::Threads)
set(ASIO_FOUND TRUE)

View File

@ -46,11 +46,14 @@ void convertToBytes(ByteStorageT& res, const T& v, const Ts&... vs)
namespace traits
{
template <typename T>
template <typename T, typename IT>
concept adc_netmessage_c = requires(const T t) { // const methods
requires std::same_as<std::iter_value_t<IT>, char>;
{ t.empty() } -> std::convertible_to<bool>;
{ t.byteSize() } -> std::convertible_to<size_t>;
{ t.bytes() } -> adc_output_char_range;
{ t.byteView() } -> adc_range_of_view_char_range;
{ t.setFromBytes(std::input_iterator<IT>) } -> std::same_as<void>;
};
} // namespace traits

View File

@ -29,6 +29,7 @@ public:
using timeout_drtn_t = timeout_clock_t::duration;
static constexpr timeout_drtn_t defaultConnectTimeout = std::chrono::seconds(5);
// static constexpr std::chrono::duration defaultConnectTimeout = std::chrono::seconds(5);
static constexpr timeout_drtn_t defaultSendTimeout = std::chrono::seconds(5);
static constexpr timeout_drtn_t defaultRecvTimeout = std::chrono::seconds(5);

100
net/adc_netservice_asio.h Normal file
View File

@ -0,0 +1,100 @@
#pragma once
/*
ABSTRACT DEVICE COMPONENTS LIBRARY
ASIO-library implementation of network service
*/
#ifdef USE_ASIO_LIBRARY
#include <asio/awaitable.hpp>
#include <asio/basic_datagram_socket.hpp>
#include <asio/basic_seq_packet_socket.hpp>
#include <asio/basic_stream_socket.hpp>
#include <asio/experimental/awaitable_operators.hpp>
#include <asio/read_until.hpp>
#include <asio/streambuf.hpp>
#include <asio/write.hpp>
#include <concepts>
namespace adc::impl
{
template <typename NetMessageT, typename InetProtoT>
class AdcNetServiceASIOStream
{
public:
using socket_t = typename InetProtoT::socket;
AdcNetServiceASIOStream(socket_t& sock) : _socket(sock) {}
virtual ~AdcNetServiceASIOStream() = default;
template <typename TimeoutT, typename CompletionTokenT>
auto asynSend(const NetMessageT& msg, const TimeoutT& timeout, CompletionTokenT&& token)
requires std::derived_from<socket_t, asio::basic_stream_socket<typename socket_t::protocol_type>>
{
using namespace asio::experimental::awaitable_operators;
auto deadline = std::chrono::steady_clock::now() + timeout;
std::error_code ec;
co_await (asio::async_write(_socket, msg.bytes(), asio::use_awaitable) && watchdog(deadline, ec));
std::forward<CompletionTokenT>(token)(ec);
}
template <typename CompletionTokenT>
auto asynSend(const NetMessageT& msg, CompletionTokenT&& token)
requires std::derived_from<socket_t, asio::basic_datagram_socket<typename socket_t::protocol_type>>
{
}
template <typename CompletionTokenT>
auto asynSend(const NetMessageT& msg, CompletionTokenT&& token)
requires std::derived_from<socket_t, asio::basic_seq_packet_socket<typename socket_t::protocol_type>>
{
}
protected:
socket_t& _socket;
asio::streambuf _streamBuffer;
template <typename TimepointT>
asio::awaitable<void> watchdog(TimepointT& deadline, std::error_code& ec)
{
ec.clear();
typename TimepointT::clock timer(co_await asio::this_coro::executor);
auto now = TimepointT::clock::template now();
while (deadline > now) {
timer.expires_at(deadline);
co_await timer.async_wait(asio::use_awaitable);
now = TimepointT::clock::template now();
}
ec = std::make_error_code(std::errc::timed_out);
throw std::system_error(ec);
}
};
} // namespace adc::impl
#endif