121 lines
4.1 KiB
C++
121 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include "../common/adc_utils.h"
|
|
#include "adc_net_concepts.h"
|
|
#include "adc_netserver.h"
|
|
|
|
namespace adc
|
|
{
|
|
|
|
|
|
/* A VERY GENERIC NETWORK CLIENT */
|
|
|
|
|
|
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();
|
|
}
|
|
|
|
|
|
// start the client: connect to server and start session
|
|
template <interfaces::adc_netsession_c SessionT, typename... NetServiceCtorArgTs>
|
|
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<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 TokenT, typename... NetServiceCtorArgTs>
|
|
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<typename SessionT::netservice_t>(std::forward<NetServiceCtorArgTs>(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<TokenT>(token))](auto ec) mutable {
|
|
// create session
|
|
std::get<0>(wrapper)(ec, {std::move(id), std::move(*srv_sptr), std::move(sess_ctx)});
|
|
},
|
|
_connectTimeout);
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
template <interfaces::adc_netservice_c ServiceT,
|
|
traits::adc_input_char_range SendMsgT,
|
|
typename TokenT,
|
|
traits::adc_time_duration_c SendTimeoutT = std::chrono::milliseconds,
|
|
traits::adc_time_duration_c RecvTimeoutT = std::chrono::milliseconds>
|
|
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<TokenT>(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
|