This commit is contained in:
2024-06-17 13:38:01 +03:00
parent 143f54b989
commit 1cefae2953
4 changed files with 137 additions and 25 deletions

View File

@@ -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