...
This commit is contained in:
parent
143f54b989
commit
1cefae2953
@ -41,6 +41,7 @@ if (ASIO_LIBRARY)
|
|||||||
|
|
||||||
set(ADC_NETWORK_HEADERS ${ADC_NETWORK_HEADERS}
|
set(ADC_NETWORK_HEADERS ${ADC_NETWORK_HEADERS}
|
||||||
net/adc_netservice_asio.h
|
net/adc_netservice_asio.h
|
||||||
|
net/adc_netsession_asio.h
|
||||||
)
|
)
|
||||||
|
|
||||||
add_compile_definitions(PUBLIC USE_ASIO_LIBRARY)
|
add_compile_definitions(PUBLIC USE_ASIO_LIBRARY)
|
||||||
|
|||||||
@ -16,6 +16,17 @@ ABSTRACT DEVICE COMPONENTS LIBRARY
|
|||||||
namespace adc
|
namespace adc
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace traits
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
// from https://stackoverflow.com/questions/74383254/concept-that-models-only-the-stdchrono-duration-types
|
||||||
|
concept adc_time_duration_c = requires {
|
||||||
|
[]<class Rep, class Period>(std::type_identity<std::chrono::duration<Rep, Period>>) {}(std::type_identity<T>());
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace traits
|
||||||
|
|
||||||
|
|
||||||
template <typename ImplT>
|
template <typename ImplT>
|
||||||
class AdcNetService
|
class AdcNetService
|
||||||
@ -28,13 +39,7 @@ public:
|
|||||||
|
|
||||||
using typename ImplT::endpoint_t;
|
using typename ImplT::endpoint_t;
|
||||||
|
|
||||||
using timeout_clock_t = std::chrono::steady_clock;
|
using typename ImplT::timeout_t;
|
||||||
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);
|
|
||||||
|
|
||||||
template <typename... ImplCtorArgTs>
|
template <typename... ImplCtorArgTs>
|
||||||
AdcNetService(ImplCtorArgTs&&... ctor_args) : _impl(std::forward<ImplCtorArgTs>(ctor_args)...)
|
AdcNetService(ImplCtorArgTs&&... ctor_args) : _impl(std::forward<ImplCtorArgTs>(ctor_args)...)
|
||||||
@ -49,22 +54,20 @@ public:
|
|||||||
|
|
||||||
// open connection
|
// open connection
|
||||||
template <typename... ArgTs>
|
template <typename... ArgTs>
|
||||||
auto asyncConnect(const endpoint_t& end_point,
|
auto asyncConnect(const endpoint_t& end_point, const timeout_t& timeout, ArgTs&&... args)
|
||||||
const timeout_drtn_t& timeout = defaultConnectTimeout,
|
|
||||||
ArgTs&&... args)
|
|
||||||
{
|
{
|
||||||
return _impl.asyncConnect(end_point, timeout, std::forward<ArgTs>(args)...);
|
return _impl.asyncConnect(end_point, timeout, std::forward<ArgTs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
|
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
|
||||||
auto asyncSend(const NetMessageT& msg, const timeout_drtn_t& timeout = defaultSendTimeout, ArgTs&&... args)
|
auto asyncSend(const NetMessageT& msg, const timeout_t& timeout, ArgTs&&... args)
|
||||||
{
|
{
|
||||||
return _impl.asyncSend(msg, timeout, std::forward<ArgTs>(args)...);
|
return _impl.asyncSend(msg, timeout, std::forward<ArgTs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
|
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
|
||||||
auto asyncReceive(const timeout_drtn_t& timeout = defaultRecvTimeout, ArgTs&&... args)
|
auto asyncReceive(const timeout_t& timeout, ArgTs&&... args)
|
||||||
{
|
{
|
||||||
return _impl.asyncReceive(timeout, std::forward<ArgTs>(args)...);
|
return _impl.asyncReceive(timeout, std::forward<ArgTs>(args)...);
|
||||||
}
|
}
|
||||||
@ -74,20 +77,20 @@ public:
|
|||||||
/* blocking operations */
|
/* blocking operations */
|
||||||
|
|
||||||
template <typename... ArgTs>
|
template <typename... ArgTs>
|
||||||
auto connect(const endpoint_t& endpoint, const timeout_drtn_t& timeout = defaultConnectTimeout, ArgTs&&... args)
|
auto connect(const endpoint_t& endpoint, const timeout_t& timeout, ArgTs&&... args)
|
||||||
{
|
{
|
||||||
return _impl.connect(endpoint, timeout, std::forward<ArgTs>(args)...);
|
return _impl.connect(endpoint, timeout, std::forward<ArgTs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
|
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
|
||||||
auto send(const NetMessageT& msg, const timeout_drtn_t& timeout = defaultSendTimeout, ArgTs&&... args)
|
auto send(const NetMessageT& msg, const timeout_t& timeout, ArgTs&&... args)
|
||||||
{
|
{
|
||||||
return _impl.send(msg, timeout, std::forward<ArgTs>(args)...);
|
return _impl.send(msg, timeout, std::forward<ArgTs>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
|
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
|
||||||
NetMessageT receive(const timeout_drtn_t& timeout = defaultRecvTimeout, ArgTs&&... args)
|
NetMessageT receive(const timeout_t& timeout, ArgTs&&... args)
|
||||||
{
|
{
|
||||||
return _impl.receive(timeout, std::forward<ArgTs>(args)...);
|
return _impl.receive(timeout, std::forward<ArgTs>(args)...);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,20 +58,24 @@ namespace adc::impl
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
template <typename InetProtoT, typename HighLevelSocketT = typename InetProtoT::socket>
|
template <traits::adc_asio_inet_proto_c InetProtoT, typename HighLevelSocketT = typename InetProtoT::socket>
|
||||||
class AdcNetServiceASIO : public InetProtoT
|
class AdcNetServiceASIO : public InetProtoT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using socket_t = typename InetProtoT::socket;
|
using socket_t = typename InetProtoT::socket;
|
||||||
using endpoint_t = typename InetProtoT::endpoint;
|
using endpoint_t = typename InetProtoT::endpoint;
|
||||||
|
|
||||||
|
using inet_proto_t = InetProtoT;
|
||||||
using high_level_socket_t = HighLevelSocketT;
|
using high_level_socket_t = HighLevelSocketT;
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::chrono::steady_clock::duration timeout_t; // nanoseconds resolution
|
||||||
|
|
||||||
#ifdef USE_OPENSSL_WITH_ASIO
|
#ifdef USE_OPENSSL_WITH_ASIO
|
||||||
|
|
||||||
static_assert(std::is_same_v<HighLevelSocketT, socket_t>
|
static_assert(std::is_same_v<HighLevelSocketT, socket_t>
|
||||||
? true
|
? true
|
||||||
: std::is_same_v<HighLevelSocketT, asio::ssl::stream<InetProtoT>>,
|
: std::is_same_v<HighLevelSocketT, asio::ssl::stream<socket_t>>,
|
||||||
"ONLY BASIC SOCKETS AND SSL::STREAM ARE SUPPORTED!!!");
|
"ONLY BASIC SOCKETS AND SSL::STREAM ARE SUPPORTED!!!");
|
||||||
|
|
||||||
static constexpr bool IsBasicSocket = std::is_same_v<high_level_socket_t, socket_t>;
|
static constexpr bool IsBasicSocket = std::is_same_v<high_level_socket_t, socket_t>;
|
||||||
@ -88,7 +92,7 @@ public:
|
|||||||
virtual ~AdcNetServiceASIO() = default;
|
virtual ~AdcNetServiceASIO() = default;
|
||||||
|
|
||||||
|
|
||||||
template <typename TimeoutT, asio::completion_token_for<void(std::error_code)> CompletionTokenT>
|
template <traits::adc_time_duration_c TimeoutT, asio::completion_token_for<void(std::error_code)> CompletionTokenT>
|
||||||
auto asyncConnect(const endpoint_t& endpoint, const TimeoutT& timeout, CompletionTokenT&& token)
|
auto asyncConnect(const endpoint_t& endpoint, const TimeoutT& timeout, CompletionTokenT&& token)
|
||||||
{
|
{
|
||||||
auto timer = getDeadlineTimer(timeout);
|
auto timer = getDeadlineTimer(timeout);
|
||||||
@ -123,7 +127,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_netmessage_c NetMessageT,
|
template <traits::adc_netmessage_c NetMessageT,
|
||||||
typename TimeoutT,
|
traits::adc_time_duration_c TimeoutT,
|
||||||
asio::completion_token_for<void(std::error_code)> CompletionTokenT>
|
asio::completion_token_for<void(std::error_code)> CompletionTokenT>
|
||||||
auto asynSend(const NetMessageT& msg, const TimeoutT& timeout, CompletionTokenT&& token)
|
auto asynSend(const NetMessageT& msg, const TimeoutT& timeout, CompletionTokenT&& token)
|
||||||
{
|
{
|
||||||
@ -171,7 +175,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <traits::adc_netmessage_c NetMessageT, typename TimeoutT, typename CompletionTokenT>
|
template <traits::adc_netmessage_c NetMessageT, traits::adc_time_duration_c TimeoutT, typename CompletionTokenT>
|
||||||
auto asyncReceive(const TimeoutT& timeout, CompletionTokenT&& token)
|
auto asyncReceive(const TimeoutT& timeout, CompletionTokenT&& token)
|
||||||
{
|
{
|
||||||
enum { starting, cancel_timer };
|
enum { starting, cancel_timer };
|
||||||
@ -241,21 +245,21 @@ public:
|
|||||||
token, _socket);
|
token, _socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TimeoutT>
|
template <traits::adc_time_duration_c TimeoutT>
|
||||||
auto connect(const endpoint_t& endpoint, const TimeoutT& timeout)
|
auto connect(const endpoint_t& endpoint, const TimeoutT& timeout)
|
||||||
{
|
{
|
||||||
std::future<void> ftr = asyncConnect(endpoint, timeout, asio::use_future);
|
std::future<void> ftr = asyncConnect(endpoint, timeout, asio::use_future);
|
||||||
ftr.get();
|
ftr.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_netmessage_c NetMessageT, typename TimeoutT>
|
template <traits::adc_netmessage_c NetMessageT, traits::adc_time_duration_c TimeoutT>
|
||||||
auto send(const NetMessageT& msg, const TimeoutT& timeout)
|
auto send(const NetMessageT& msg, const TimeoutT& timeout)
|
||||||
{
|
{
|
||||||
std::future<void> ftr = asyncSend(msg, timeout, asio::use_future);
|
std::future<void> ftr = asyncSend(msg, timeout, asio::use_future);
|
||||||
ftr.get();
|
ftr.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_netmessage_c NetMessageT, typename TimeoutT>
|
template <traits::adc_netmessage_c NetMessageT, traits::adc_time_duration_c TimeoutT>
|
||||||
auto receive(const TimeoutT& timeout)
|
auto receive(const TimeoutT& timeout)
|
||||||
{
|
{
|
||||||
std::future<NetMessageT> ftr = asyncReceive(timeout, asio::use_future);
|
std::future<NetMessageT> ftr = asyncReceive(timeout, asio::use_future);
|
||||||
@ -290,13 +294,13 @@ protected:
|
|||||||
|
|
||||||
asio::streambuf _streamBuffer;
|
asio::streambuf _streamBuffer;
|
||||||
|
|
||||||
template <typename TimeoutT>
|
template <traits::adc_time_duration_c TimeoutT>
|
||||||
std::unique_ptr<asio::steady_timer> getDeadlineTimer(const TimeoutT& timeout, bool arm = true)
|
std::unique_ptr<asio::steady_timer> getDeadlineTimer(const TimeoutT& timeout, bool arm = true)
|
||||||
{
|
{
|
||||||
std::unique_ptr<asio::steady_timer> timer(_socket.get_executor());
|
std::unique_ptr<asio::steady_timer> timer(_socket.get_executor());
|
||||||
|
|
||||||
if (arm) {
|
if (arm) {
|
||||||
timer->expires_after(timeout);
|
timer->expires_after(std::chrono::duration_cast<timeout_t>(timeout));
|
||||||
|
|
||||||
timer->async_wait([this](const std::error_code& ec) {
|
timer->async_wait([this](const std::error_code& ec) {
|
||||||
if (!ec) {
|
if (!ec) {
|
||||||
@ -311,10 +315,25 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
typedef AdcNetService<impl::AdcNetServiceASIO<asio::ip::tcp>> AdcNetServiceAsioTcp;
|
typedef AdcNetService<impl::AdcNetServiceASIO<asio::ip::tcp>> AdcNetServiceAsioTcp;
|
||||||
|
typedef AdcNetService<impl::AdcNetServiceASIO<asio::ip::tcp, asio::ssl::stream<asio::ip::tcp>>> AdcNetServiceAsioTls;
|
||||||
typedef AdcNetService<impl::AdcNetServiceASIO<asio::local::seq_packet_protocol>> AdcNetServiceAsioLocalSeqPack;
|
typedef AdcNetService<impl::AdcNetServiceASIO<asio::local::seq_packet_protocol>> AdcNetServiceAsioLocalSeqPack;
|
||||||
typedef AdcNetService<impl::AdcNetServiceASIO<asio::local::stream_protocol>> AdcNetServiceAsioLocalStream;
|
typedef AdcNetService<impl::AdcNetServiceASIO<asio::local::stream_protocol>> AdcNetServiceAsioLocalStream;
|
||||||
|
|
||||||
} // namespace adc::impl
|
} // namespace adc::impl
|
||||||
|
|
||||||
|
|
||||||
|
namespace adc::traits
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept adc_netservice_asio_c = requires {
|
||||||
|
typename T::inet_proto_t;
|
||||||
|
typename T::high_level_socket_t;
|
||||||
|
|
||||||
|
requires std::derived_from<T,
|
||||||
|
adc::impl::AdcNetServiceASIO<typename T::inet_proto_t, typename T::high_level_socket_t>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace adc::traits
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
89
net/adc_netsession_asio.h
Normal file
89
net/adc_netsession_asio.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
ABSTRACT DEVICE COMPONENTS LIBRARY
|
||||||
|
|
||||||
|
ASIO-library implementation of network server session
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_ASIO_LIBRARY
|
||||||
|
|
||||||
|
#include "adc_netservice_asio.h"
|
||||||
|
|
||||||
|
// #ifdef USE_SPDLOG_LIBRARY
|
||||||
|
// #include "adc_netserver_spdlog.h"
|
||||||
|
// #endif // USE_SPDLOG_LIBRARY
|
||||||
|
|
||||||
|
|
||||||
|
namespace adc::impl
|
||||||
|
{
|
||||||
|
|
||||||
|
template <traits::adc_netservice_asio_c NetServiceT, typename ContextT = std::nullptr_t>
|
||||||
|
class AdcNetServerSessionASIO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::string_view session_ident_t;
|
||||||
|
|
||||||
|
typedef NetServiceT netservice_t;
|
||||||
|
|
||||||
|
typedef ContextT context_t;
|
||||||
|
|
||||||
|
typedef std::chrono::duration<double, std::milli> timeout_t;
|
||||||
|
|
||||||
|
static constexpr timeout_t defaultSendTimeout = std::chrono::milliseconds(5000);
|
||||||
|
static constexpr timeout_t defaultRecvTimeout = std::chrono::milliseconds(5000);
|
||||||
|
|
||||||
|
template <traits::adc_input_char_range R>
|
||||||
|
AdcNetServerSessionASIO(netservice_t::socket_t&& sock, const R& sess_ident, ContextT&& context = nullptr)
|
||||||
|
: _socket(std::move(sock)),
|
||||||
|
_netService(_socket),
|
||||||
|
_sessionIdent(sess_ident.begin(), sess_ident.end()),
|
||||||
|
_context(context),
|
||||||
|
_sendTimeout(defaultSendTimeout),
|
||||||
|
_recvTimeout(defaultRecvTimeout)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~AdcNetServerSessionASIO()
|
||||||
|
{
|
||||||
|
_netService.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::adc_time_duration_c TimeoutT>
|
||||||
|
AdcNetServerSessionASIO& setDefaultTimeouts(const TimeoutT& send_timeout = defaultSendTimeout,
|
||||||
|
const TimeoutT& recv_timeout = defaultRecvTimeout)
|
||||||
|
{
|
||||||
|
_sendTimeout = send_timeout;
|
||||||
|
_recvTimeout = recv_timeout;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
session_ident_t sessionIdent() const
|
||||||
|
{
|
||||||
|
return {_sessionIdent.begin(), _sessionIdent.end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void start() {}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void stop() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
netservice_t::socket_t _socket;
|
||||||
|
netservice_t _netService;
|
||||||
|
|
||||||
|
std::string _sessionIdent;
|
||||||
|
ContextT _context;
|
||||||
|
|
||||||
|
timeout_t _sendTimeout, _recvTimeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace adc::impl
|
||||||
|
|
||||||
|
|
||||||
|
#endif // USE_ASIO_LIBRARY
|
||||||
Loading…
x
Reference in New Issue
Block a user