#pragma once #include "../common/adc_utils.h" #include "adc_net_concepts.h" #include "adc_netserver.h" namespace adc { /* A VERY GENERIC NETWORK CLIENT */ template > class AdcGenericNetClient : public LoggerT, public AdcNetSessionManager { public: typedef IdentT client_ident_t; typedef LoggerT logger_t; template AdcGenericNetClient(const IdentT& ident, LoggerCtorArgTs&&... args) : _clientIdent(ident), LoggerT(std::forward(args)...) { } virtual ~AdcGenericNetClient() { stopAllSessions(); } // start the client: connect to server and start session template void start(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(std::forward(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(id, std::move(*srv_sptr), sess_ctx); startSession(sess); } }, _connectTimeout); } template void start(const SessionT::netservice_t::endpoint_t& endpoint, SessionT::netsession_ident_t id, SessionT::netsession_ctx_t sess_ctx, TokenT&& token, NetServiceCtorArgTs&&... ctor_args) { auto srv_sptr = std::make_shared(std::forward(ctor_args)...); // try to connect to server and create session srv_sptr->asyncConnect( endpoint, [id = std::move(id), sess_ctx = std::move(sess_ctx), srv_sptr, wrapper = traits::adc_pf_wrapper(std::forward(token))](auto ec) mutable { // create session std::get<0>(wrapper)(ec, {std::move(id), std::move(*srv_sptr), std::move(sess_ctx)}); }, _connectTimeout); } template void setConnectTimeout(const DT& timeout) { _connectTimeout = std::chrono::duration_cast(timeout); } auto getConnectionTimeout() const { return _connectTimeout; } protected: client_ident_t _clientIdent; std::chrono::milliseconds _connectTimeout = std::chrono::milliseconds(5000); template auto asyncSendRecv(ServiceT& netservice, const SendMsgT& send_msg, TokenT&& token, const SendTimeoutT& send_timeout = std::chrono::milliseconds(5000), const RecvTimeoutT& recv_timeout = std::chrono::milliseconds(5000)) { return netservice.asyncSend( send_msg, [&netservice, recv_timeout, wrapper = traits::adc_pf_wrapper(std::forward(token)), this](auto err) { if (err) { this->logError("An error occured while sending the message: {}", ServiceT::formattableError(err)); } else { netservice.asyncReceive(std::get<0>(wrapper), recv_timeout); } }, send_timeout); } }; } // namespace adc