#pragma once #include "../common/adc_utils.h" #include "adc_device_netmsg.h" #include "adc_netclient.h" namespace adc { template > class AdcDeviceNetClient : public AdcGenericNetClient { typedef AdcGenericNetClient base_t; public: template class Session : public std::enable_shared_from_this> { public: typedef SessionIdentT netsession_ident_t; typedef NetServiceT netservice_t; struct netsession_ctx_t { AdcDeviceNetClient* clientPtr; std::chrono::milliseconds recvTimeout; std::chrono::milliseconds sendTimeout; }; typedef std::vector message_t; // Session(const netsession_ident_t& id, netservice_t srv, AdcDeviceNetServer* srv_ptr) Session(const netsession_ident_t& id, netservice_t srv, netsession_ctx_t ctx) : _ident(id), _netService(std::move(srv)), _clientPtr(ctx.clientPtr), _recvTimeout(ctx.recvTimeout), _sendTimeout(ctx.sendTimeout) { _clientPtr->logInfo("Create client-to-server session with ID = {} (addr = {}, thread = {})", _ident, (void*)this, utils::AdcThisThreadId()); } virtual ~Session() { _clientPtr->logInfo("Delete client-to-server session with ID = {} (addr = {}, thread = {})", _ident, (void*)this, utils::AdcThisThreadId()); } netsession_ident_t ident() const { return _ident; } void start() { _clientPtr->logInfo("Start client-to-server session with ID = {} (addr = {}, thread = {})", _ident, (void*)this, utils::AdcThisThreadId()); } void stop() { _clientPtr->logInfo("Stop client-to-server session with ID = {} (addr = {}, thread = {})", _ident, (void*)this, utils::AdcThisThreadId()); _netService.close(); } protected: netsession_ident_t _ident; netservice_t _netService; AdcDeviceNetClient* _clientPtr; std::chrono::milliseconds _recvTimeout = std::chrono::seconds(5); std::chrono::milliseconds _sendTimeout = std::chrono::seconds(5); // helper methods std::function _defaultRecvCallback = [this](auto err, auto msg) { if (err) { _clientPtr->logError("An error occured while receiving server respond: {}", netservice_t::formattableError(err)); } else { AdcDeviceProtoMessage dev_msg(msg); if (!dev_msg.isValid()) { _clientPtr->logError("Invalid server respond"); return; } if (dev_msg.isACK()) { } else if (dev_msg.isERROR()) { } else { _clientPtr->logError("Unexpectable server respond"); } } }; template auto asyncSendRecv(const SendMsgT& send_msg, TokenT&& token) { return _netService.asyncSend( send_msg, [wrapper = traits::adc_pf_wrapper(std::forward(token)), this](auto err) { if (err) { this->logError("An error occured while sending the message: {}", netservice_t::formattableError(err)); } else { _netService.asyncReceive(std::get<0>(wrapper), _recvTimeout); } }, _sendTimeout); } }; // end of 'Session' class declaration using base_t::base_t; virtual ~AdcDeviceNetClient() {} }; } // namespace adc