#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 namespace adc::impl { template class AdcNetServiceASIOStream { public: using socket_t = typename InetProtoT::socket; AdcNetServiceASIOStream(socket_t& sock) : _socket(sock) {} virtual ~AdcNetServiceASIOStream() = default; template auto asynSend(const NetMessageT& msg, const TimeoutT& timeout, CompletionTokenT&& token) requires std::derived_from> { 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(token)(ec); } template auto asynSend(const NetMessageT& msg, CompletionTokenT&& token) requires std::derived_from> { } template auto asynSend(const NetMessageT& msg, CompletionTokenT&& token) requires std::derived_from> { } protected: socket_t& _socket; asio::streambuf _streamBuffer; 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