diff --git a/cxx/comm_server.h b/cxx/comm_server.h index 20a0d05..08495b2 100644 --- a/cxx/comm_server.h +++ b/cxx/comm_server.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -54,12 +55,14 @@ public: template - asio::awaitable listen(MccServerEndpoint endpoint, CtorArgTs&&... ctor_args) + asio::awaitable listen(std::derived_from auto endpoint, CtorArgTs&&... ctor_args) { + bool exit_flag = false; + if (!endpoint.isValid()) { _serverLogger->error("Cannot start listening! Invalid endpoint string representation ('{}')!", endpoint.endpoint()); - co_return; + co_return exit_flag; } // add root path to endpoint one @@ -80,21 +83,26 @@ public: s_port.open(pt.string(), ec); if (ec) { _serverLogger->error("Cannot open serial device '{}' (Error = '{}')!", pt.string(), ec.message()); - co_return; + co_return exit_flag; } - listen(std::move(s_port)); + // asio::co_spawn(_asioContext, listen(std::move(s_port)), asio::detached); + co_return listen(std::move(s_port)); } else if (endpoint.isLocal()) { // create abstract namespace socket endpoint if its path starts from '@' symbol endpoint.makeAbstract('@'); if (endpoint.isLocalStream()) { - listen(asio::local::stream_protocol::endpoint(pt.string())); + co_return listen(asio::local::stream_protocol::endpoint(pt.string())); + // asio::co_spawn(_asioContext, listen(asio::local::stream_protocol::endpoint(pt.string())), + // asio::detached); } else if (endpoint.isLocalSeqpacket()) { - listen(asio::local::seq_packet_protocol::endpoint(pt.string())); + co_return listen(asio::local::seq_packet_protocol::endpoint(pt.string())); + // asio::co_spawn(_asioContext, listen(asio::local::seq_packet_protocol::endpoint(pt.string())), + // asio::detached); } else { - co_return; // ???!!!! + co_return exit_flag; // ???!!!! } } else if (endpoint.isTCP()) { // resolve hostname @@ -103,17 +111,30 @@ public: auto r_result = co_await res.async_resolve(endpoint.host(), endpoint.portView(), asio::deferred); - listen(std::move(*r_result.begin())); + for (auto const& epn : r_result) { + exit_flag = co_await listen(epn); + if (exit_flag) { + break; + } + } + if (!exit_flag) { + _serverLogger->error("Cannot start listening on any resolved endpoints!"); + co_return exit_flag; + } + + // listen(std::move(*r_result.begin())); } catch (const std::system_error& err) { _serverLogger->error("An error occured while resolving '{}' hostname (Error = '{}')", endpoint.host(), err.code().message()); - co_return; + co_return exit_flag; } } + + co_return true; } - void listen(traits::mcc_endpoint_c auto endpoint) + asio::awaitable listen(traits::mcc_endpoint_c auto endpoint) { using epn_t = std::decay_t; @@ -124,19 +145,40 @@ public: if (!endpoint.is_open()) { if (ec) { // ?????????? - _serverLogger->error("Serial port was not open!"); - return; + _serverLogger->error("Serial port was not open! Do not start waiting for commands!"); + co_return false; } } _serialPorts.emplace_back(std::move(endpoint)); - } else if constexpr (traits::is_tcp_proto) { - } else if constexpr (traits::is_local_stream_proto) { - } else if constexpr (traits::is_local_seqpack_proto) { + } else if constexpr (traits::is_tcp_proto || traits::is_local_stream_proto || + traits::is_local_seqpack_proto) { + try { + std::stringstream st; + auto acc = epn_t::protocol_type::acceptor(_asioContext, endpoint); + st << acc.local_endpoint(); + _serverLogger->info("Try to start listening at <{}> endpoint ...", st.str()); + + if constexpr (traits::is_tcp_proto) { + _tcpAcceptors.emplace_back(std::move(acc)); + } else if constexpr (traits::is_local_stream_proto) { + _localStreamAcceptors.emplace_back(std::move(acc)); + } else if constexpr (traits::is_local_seqpack_proto) { + _localSeqpackAcceptors.emplace_back(std::move(acc)); + } else { + static_assert(false, "INVALID ENDPOINT!!!"); + } + + + } catch (const std::system_error& err) { + _serverLogger->error("An error occured while creating of connection acceptor! ec = '{}'", err.what()); + } } else { static_assert(false, "INVALID ENDPOINT!!!"); } + + co_return true; } @@ -241,37 +283,8 @@ private: std::vector _localStreamAcceptors; std::vector _localSeqpackAcceptors; - void startAccept(traits::mcc_endpoint_c auto endpoint) - { - using epn_t = std::decay_t; - - try { - std::stringstream st; - auto acc = epn_t::protocol_type::endpoint(_asioContext, endpoint); - st << acc.local_endpoint(); - _serverLogger->info("Try to start listening at <{}> endpoint ...", st.str()); - - if constexpr (traits::is_tcp_proto) { - _tcpAcceptors.emplace_back(std::move(acc)); - } else if constexpr (traits::is_local_stream_proto) { - _localStreamAcceptors.emplace_back(std::move(acc)); - } else if constexpr (traits::is_local_seqpack_proto) { - _localSeqpackAcceptors.emplace_back(std::move(acc)); - } else { - static_assert(false, "INVALID ENDPOINT!!!"); - } - - - } catch (const std::system_error& err) { - _serverLogger->error("An error occured while creating of connection acceptor! ec = '{}'", err.what()); - } - } - - template - void doAccept() - { - } + asio::awaitable startSession() {} // helpers template