add AdcGenericNetClient class

This commit is contained in:
Timur A. Fatkhullin 2024-11-14 23:16:08 +03:00
parent 78a9e53d18
commit 285f8de1f7
6 changed files with 130 additions and 16 deletions

View File

@ -202,6 +202,12 @@ public:
return _isValid; return _isValid;
} }
auto endpoint() const
{
return _endpoint;
}
template <traits::adc_view_or_output_char_range R> template <traits::adc_view_or_output_char_range R>
R proto() const R proto() const
{ {

View File

@ -181,7 +181,7 @@ concept adc_netsession_c =
requires adc_netservice_c<typename SESST::netservice_t>; requires adc_netservice_c<typename SESST::netservice_t>;
typename SESST::netsession_ctx_t; typename SESST::netsession_ctx_t;
requires std::constructible_from<SESST, const typename SESST::netsession_ident_t, requires std::constructible_from<SESST, typename SESST::netsession_ident_t,
// std::shared_ptr<typename SESST::netservice_t>, // std::shared_ptr<typename SESST::netservice_t>,
typename SESST::netservice_t, typename SESST::netsession_ctx_t>; typename SESST::netservice_t, typename SESST::netsession_ctx_t>;

87
net/adc_netclient.h Normal file
View File

@ -0,0 +1,87 @@
#pragma once
#include "../common/adc_utils.h"
#include "adc_net_concepts.h"
#include "adc_netserver.h"
namespace adc
{
/* */
template <typename IdentT = std::string, interfaces::adc_logger_c LoggerT = utils::AdcOstreamLogger<char>>
class AdcGenericNetClient : public LoggerT, public AdcNetSessionManager
{
public:
typedef IdentT client_ident_t;
typedef LoggerT logger_t;
template <typename... LoggerCtorArgTs>
AdcGenericNetClient(const IdentT& ident, LoggerCtorArgTs&&... args)
: _clientIdent(ident), LoggerT(std::forward<LoggerCtorArgTs>(args)...)
{
}
virtual ~AdcGenericNetClient()
{
stopAllSessions();
}
template <interfaces::adc_netsession_c SessionT, typename... NetServiceCtorArgTs>
void asyncConnect(const SessionT::netservice_t::endpoint_t& endpoint,
SessionT::netsession_ident_t id,
SessionT::netsession_ctx_t sess_ctx,
NetServiceCtorArgTs&&... ctor_args)
{
auto srv_sptr =
std::make_shared<typename SessionT::netservice_t>(std::forward<NetServiceCtorArgTs>(ctor_args)...);
srv_sptr->asyncConnect(
endpoint,
[id = std::move(id), sess_ctx = std::move(sess_ctx), srv_sptr, this](auto ec) {
if (ec) {
this->logError("Cannot connect to server: {}", SessionT::netservice_t::formattableError(ec));
} else {
auto sess = std::make_shared<SessionT>(id, std::move(*srv_sptr), sess_ctx);
startSession(sess);
}
},
_connectTimeout);
}
template <interfaces::adc_netsession_c SessionT, typename... NetServiceCtorArgTs>
void connect(const SessionT::netservice_t::endpoint_t& endpoint,
SessionT::netsession_ident_t id,
SessionT::netsession_ctx_t sess_ctx,
NetServiceCtorArgTs&&... ctor_args)
{
typename SessionT::netservice_t srv(std::forward<NetServiceCtorArgTs>(ctor_args)...);
srv.connect(endpoint, _connectTimeout);
auto sess = std::make_shared<SessionT>(std::move(id), std::move(srv), std::move(sess_ctx));
startSession(sess);
}
template <traits::adc_time_duration_c DT>
void setConnectTimeout(const DT& timeout)
{
_connectTimeout = std::chrono::duration_cast<decltype(_connectTimeout)>(timeout);
}
auto getConnectionTimeout() const
{
return _connectTimeout;
}
protected:
client_ident_t _clientIdent;
std::chrono::milliseconds _connectTimeout = std::chrono::milliseconds(5000);
};
} // namespace adc

View File

@ -371,7 +371,20 @@ public:
}; };
void setAcceptTimeout(const traits::adc_time_duration_c auto& timeout)
{
_acceptTimeout = std::chrono::duration_cast<decltype(_acceptTimeout)>(timeout);
}
auto getAcceptTimeout() const
{
return _acceptTimeout;
}
// helper methods for logging // helper methods for logging
template <traits::formattable... Ts> template <traits::formattable... Ts>
void logMessage(LoggerT::loglevel_t level, std::format_string<Ts...> fmt, Ts&&... args) void logMessage(LoggerT::loglevel_t level, std::format_string<Ts...> fmt, Ts&&... args)
{ {
@ -397,6 +410,8 @@ public:
} }
protected: protected:
std::chrono::seconds _acceptTimeout = std::chrono::seconds::max();
// template <interfaces::adc_netsession_c SessionT> // template <interfaces::adc_netsession_c SessionT>
// inline static std::unordered_map<const AdcGenericNetServer*, bool> _isListening{}; // inline static std::unordered_map<const AdcGenericNetServer*, bool> _isListening{};
template <interfaces::adc_netsession_c SessionT> template <interfaces::adc_netsession_c SessionT>
@ -412,24 +427,28 @@ protected:
template <typename SessionT, typename AT, typename IDT, typename CTXT> template <typename SessionT, typename AT, typename IDT, typename CTXT>
void doAccept(std::shared_ptr<AT> acceptor, IDT id, CTXT sess_ctx) void doAccept(std::shared_ptr<AT> acceptor, IDT id, CTXT sess_ctx)
{ {
acceptor->asyncAccept([acceptor, id = std::move(id), sess_ctx = std::move(sess_ctx), this]( acceptor->asyncAccept(
auto ec, typename SessionT::netservice_t srv) mutable { [acceptor, id = std::move(id), sess_ctx = std::move(sess_ctx), this](
if (!ec) { auto ec, typename SessionT::netservice_t srv) mutable {
logInfo( if (!ec) {
"Client connection is succesfully accepted! Client endpoint: {} (server addr = {}, thread = {})", logInfo(
srv.remoteEndpoint(), (void*)this, utils::AdcThisThreadId()); "Client connection is succesfully accepted! Client endpoint: {} (server addr = {}, thread = "
"{})",
srv.remoteEndpoint(), (void*)this, utils::AdcThisThreadId());
auto sess = std::make_shared<SessionT>(id, std::move(srv), sess_ctx); auto sess = std::make_shared<SessionT>(id, std::move(srv), sess_ctx);
startSession(sess); startSession(sess);
_isListening<SessionT>[this][id] = true; _isListening<SessionT>[this][id] = true;
doAccept<SessionT>(acceptor, std::move(id), std::move(sess_ctx)); doAccept<SessionT>(acceptor, std::move(id), std::move(sess_ctx));
} else { } else {
this->logError("Cannot start accepting connection: {}", SessionT::netservice_t::formattableError(ec)); this->logError("Cannot start accepting connection: {}",
SessionT::netservice_t::formattableError(ec));
_isListening<SessionT>[this][id] = false; _isListening<SessionT>[this][id] = false;
} }
}); },
_acceptTimeout);
} }
}; };

View File

@ -48,6 +48,7 @@ public:
#endif #endif
{ {
if (!endpoint.isValid()) { if (!endpoint.isValid()) {
this->logError("Invalid given endpoint: <{}>", endpoint.endpoint());
return; return;
} }

View File

@ -142,6 +142,7 @@ int main(int argc, char* argv[])
logger->set_level(spdlog::level::debug); logger->set_level(spdlog::level::debug);
// server_t server("TEST SRV", io_ctx, logger, "[%Y-%m-%d %T.%e][%l]: %v"); // server_t server("TEST SRV", io_ctx, logger, "[%Y-%m-%d %T.%e][%l]: %v");
server_t server("TEST SRV", io_ctx, logger); server_t server("TEST SRV", io_ctx, logger);
// server.setAcceptTimeout(std::chrono::seconds(5));
// using server_t = adc::impl::AdcDeviceNetServerASIO<>; // using server_t = adc::impl::AdcDeviceNetServerASIO<>;
// server_t server("TEST SRV", io_ctx); // server_t server("TEST SRV", io_ctx);