#pragma once /* ABSTRACT DEVICE COMPONENTS LIBRARY ASIO-library implementation of network service */ #ifdef USE_ASIO_LIBRARY #include #include #include #include #include #include #include #include > #include #include #include namespace adc::impl { template class AdcNetServiceASIOStream { public: using socket_t = typename InetProtoT::socket; AdcNetServiceASIOStream(socket_t& sock) : _socket(sock) {} virtual ~AdcNetServiceASIOStream() = default; template CompletionTokenT> auto asynSend(const NetMessageT& msg, const TimeoutT& timeout, CompletionTokenT&& token) { // using namespace asio::experimental::awaitable_operators; // auto deadline = std::chrono::steady_clock::now() + timeout; std::unique_ptr timer(_socket.get_executor()); timer->expires_after(timeout); timer->async_wait([this, timer = std::move(timer)](const std::error_code& ec) { if (!ec) { _socket.cancel(std::make_error_code(std::errc::timed_out)); } }); if constexpr (std::derived_from>) { return asio::async_write(_socket, createConstBufferSequence(msg), std::forward(token)); } else if constexpr (std::derived_from>) { return _socket.async_send(createConstBufferSequence(msg), std::forward(token)); } else if constexpr (std::derived_from>) { return _socket.async_send(createConstBufferSequence(msg), std::forward(token)); } else { static_assert(false, "UNKNOWN ASIO-LIBRARY SOCKET TYPE!!!"); } // std::error_code ec; // co_await (asyncSendImpl(msg) && watchdog(deadline, ec)); // std::forward(token)(ec); // co_return asio::async_compose( // [ec](auto& self, const std::error_code& = {}) { self.complete(ec); }, token, _socket); } template auto asyncReceive(const TimeoutT& timeout, CompletionTokenT&& token) { } protected: socket_t& _socket; asio::streambuf _streamBuffer; std::vector createConstBufferSequence(const NetMessageT& msg) { std::vector buff; for (const auto& el : msg.template bytesView>()) { buff.emplace_back(asio::const_buffer(el)); } return buff; } asio::awaitable asyncSendImpl(const NetMessageT& msg) { // for (const auto& buff : msg.bytesView()) { if constexpr (std::derived_from>) { // asio::async_write(_socket, buff, asio::use_awaitable); co_await asio::async_write(_socket, msg.bytesView(), asio::use_awaitable); } else if constexpr (std::derived_from>) { co_await _socket.async_send(msg.bytesView(), asio::use_awaitable); } else if constexpr (std::derived_from>) { co_await _socket.async_send(msg.bytesView(), asio::use_awaitable); } else { static_assert(false, "UNKNOWN ASIO-LIBRARY SOCKET TYPE!!!"); } // } } template asio::awaitable 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