...
This commit is contained in:
parent
143f54b989
commit
1cefae2953
@ -41,6 +41,7 @@ if (ASIO_LIBRARY)
|
||||
|
||||
set(ADC_NETWORK_HEADERS ${ADC_NETWORK_HEADERS}
|
||||
net/adc_netservice_asio.h
|
||||
net/adc_netsession_asio.h
|
||||
)
|
||||
|
||||
add_compile_definitions(PUBLIC USE_ASIO_LIBRARY)
|
||||
|
||||
@ -16,6 +16,17 @@ ABSTRACT DEVICE COMPONENTS LIBRARY
|
||||
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>
|
||||
class AdcNetService
|
||||
@ -28,13 +39,7 @@ public:
|
||||
|
||||
using typename ImplT::endpoint_t;
|
||||
|
||||
using timeout_clock_t = std::chrono::steady_clock;
|
||||
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);
|
||||
using typename ImplT::timeout_t;
|
||||
|
||||
template <typename... ImplCtorArgTs>
|
||||
AdcNetService(ImplCtorArgTs&&... ctor_args) : _impl(std::forward<ImplCtorArgTs>(ctor_args)...)
|
||||
@ -49,22 +54,20 @@ public:
|
||||
|
||||
// open connection
|
||||
template <typename... ArgTs>
|
||||
auto asyncConnect(const endpoint_t& end_point,
|
||||
const timeout_drtn_t& timeout = defaultConnectTimeout,
|
||||
ArgTs&&... args)
|
||||
auto asyncConnect(const endpoint_t& end_point, const timeout_t& timeout, ArgTs&&... args)
|
||||
{
|
||||
return _impl.asyncConnect(end_point, timeout, std::forward<ArgTs>(args)...);
|
||||
}
|
||||
|
||||
|
||||
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)...);
|
||||
}
|
||||
|
||||
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)...);
|
||||
}
|
||||
@ -74,20 +77,20 @@ public:
|
||||
/* blocking operations */
|
||||
|
||||
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)...);
|
||||
}
|
||||
|
||||
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)...);
|
||||
}
|
||||
|
||||
|
||||
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)...);
|
||||
}
|
||||
|
||||
@ -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
|
||||
{
|
||||
public:
|
||||
using socket_t = typename InetProtoT::socket;
|
||||
using endpoint_t = typename InetProtoT::endpoint;
|
||||
|
||||
using inet_proto_t = InetProtoT;
|
||||
using high_level_socket_t = HighLevelSocketT;
|
||||
|
||||
|
||||
typedef std::chrono::steady_clock::duration timeout_t; // nanoseconds resolution
|
||||
|
||||
#ifdef USE_OPENSSL_WITH_ASIO
|
||||
|
||||
static_assert(std::is_same_v<HighLevelSocketT, socket_t>
|
||||
? 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!!!");
|
||||
|
||||
static constexpr bool IsBasicSocket = std::is_same_v<high_level_socket_t, socket_t>;
|
||||
@ -88,7 +92,7 @@ public:
|
||||
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 timer = getDeadlineTimer(timeout);
|
||||
@ -123,7 +127,7 @@ public:
|
||||
}
|
||||
|
||||
template <traits::adc_netmessage_c NetMessageT,
|
||||
typename TimeoutT,
|
||||
traits::adc_time_duration_c TimeoutT,
|
||||
asio::completion_token_for<void(std::error_code)> CompletionTokenT>
|
||||
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)
|
||||
{
|
||||
enum { starting, cancel_timer };
|
||||
@ -241,21 +245,21 @@ public:
|
||||
token, _socket);
|
||||
}
|
||||
|
||||
template <typename TimeoutT>
|
||||
template <traits::adc_time_duration_c TimeoutT>
|
||||
auto connect(const endpoint_t& endpoint, const TimeoutT& timeout)
|
||||
{
|
||||
std::future<void> ftr = asyncConnect(endpoint, timeout, asio::use_future);
|
||||
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)
|
||||
{
|
||||
std::future<void> ftr = asyncSend(msg, timeout, asio::use_future);
|
||||
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)
|
||||
{
|
||||
std::future<NetMessageT> ftr = asyncReceive(timeout, asio::use_future);
|
||||
@ -290,13 +294,13 @@ protected:
|
||||
|
||||
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> timer(_socket.get_executor());
|
||||
|
||||
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) {
|
||||
if (!ec) {
|
||||
@ -311,10 +315,25 @@ protected:
|
||||
|
||||
|
||||
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::stream_protocol>> AdcNetServiceAsioLocalStream;
|
||||
|
||||
} // 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
|
||||
|
||||
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