...
This commit is contained in:
@@ -98,6 +98,11 @@ public:
|
||||
typedef SessionIdentT netsession_ident_t;
|
||||
typedef NetServiceT netservice_t;
|
||||
|
||||
// default server respond type
|
||||
typedef std::vector<std::string> default_server_resp_t;
|
||||
// asynchronous callback callable type for ADC device getter/setter/executor
|
||||
typedef std::function<void(ServerResponseType, default_server_resp_t)> async_callback_func_t;
|
||||
|
||||
struct netsession_ctx_t {
|
||||
AdcDeviceNetClient* clientPtr;
|
||||
std::chrono::milliseconds recvTimeout;
|
||||
@@ -147,21 +152,14 @@ public:
|
||||
|
||||
// ADC device helper methods (blocking)
|
||||
|
||||
typedef std::vector<std::string> default_server_resp_t;
|
||||
|
||||
// get names of devices
|
||||
template <traits::adc_range_of_output_char_range R>
|
||||
R deviceNames(ServerResponseType& rtype)
|
||||
{
|
||||
typename netservice_t::send_msg_t bytes;
|
||||
|
||||
AdcDeviceProtoMessage msg(bytes);
|
||||
msg.names();
|
||||
using m_t = std::remove_cvref_t<decltype(msg)>;
|
||||
|
||||
// expected respond: ACK NAMES DEV1 DEV2 ...
|
||||
// return DEV1 DEV2 ... (or error description 'code category what')
|
||||
return _getFromServer<R>(m_t::NAMES_KEY, bytes, rtype);
|
||||
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_NAMES, rtype);
|
||||
}
|
||||
|
||||
default_server_resp_t deviceNames(ServerResponseType& rtype)
|
||||
@@ -173,15 +171,10 @@ public:
|
||||
template <traits::adc_range_of_output_char_range R, traits::adc_input_char_range DevNameT>
|
||||
R bindDevice(DevNameT&& dev_name, ServerResponseType& rtype)
|
||||
{
|
||||
typename netservice_t::send_msg_t bytes;
|
||||
|
||||
AdcDeviceProtoMessage msg(bytes);
|
||||
msg.device(std::forward<DevNameT>(dev_name));
|
||||
using m_t = std::remove_cvref_t<decltype(msg)>;
|
||||
|
||||
// expected respond: ACK DEVICE DEV_NAME
|
||||
// return DEV_NAME ... (or error description 'code category what')
|
||||
return _getFromServer<R>(m_t::DEVICE_KEY, bytes, rtype);
|
||||
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_DEVICE, rtype,
|
||||
std::forward<DevNameT>(dev_name));
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range DevNameT>
|
||||
@@ -195,16 +188,9 @@ public:
|
||||
template <traits::adc_range_of_output_char_range R, traits::adc_input_char_range CmdNameT>
|
||||
R exec(CmdNameT&& cmd_name, ServerResponseType& rtype)
|
||||
{
|
||||
typename netservice_t::send_msg_t bytes;
|
||||
|
||||
AdcDeviceProtoMessage msg(bytes);
|
||||
msg.cmd(std::forward<CmdNameT>(cmd_name));
|
||||
using m_t = std::remove_cvref_t<decltype(msg)>;
|
||||
|
||||
|
||||
// expected respond: ACK CMD CMD_NAME
|
||||
// return CMD_NAME ... (or error description 'code category what')
|
||||
return _getFromServer<R>(m_t::CMD_KEY, bytes, rtype);
|
||||
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_CMD, rtype, std::forward<CmdNameT>(cmd_name));
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range CmdNameT>
|
||||
@@ -218,15 +204,10 @@ public:
|
||||
template <traits::adc_range_of_output_char_range R, traits::adc_input_char_range AttrNameT>
|
||||
R getAttr(AttrNameT&& attr_name, ServerResponseType& rtype)
|
||||
{
|
||||
typename netservice_t::send_msg_t bytes;
|
||||
|
||||
AdcDeviceProtoMessage msg(bytes);
|
||||
msg.get(std::forward<AttrNameT>(attr_name));
|
||||
using m_t = std::remove_cvref_t<decltype(msg)>;
|
||||
|
||||
// expected respond: ACK GET ATTR_NAME ATTR_VALUE
|
||||
// return ATTR_NAME ATTR_VALUE (or error description 'code category what')
|
||||
return _getFromServer<R>(m_t::GET_KEY, bytes, rtype);
|
||||
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_GET, rtype,
|
||||
std::forward<AttrNameT>(attr_name));
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range AttrNameT>
|
||||
@@ -243,15 +224,10 @@ public:
|
||||
typename... ValueTs>
|
||||
R setAttr(AttrNameT&& attr_name, ServerResponseType& rtype, ValueT&& value, ValueTs&&... values)
|
||||
{
|
||||
typename netservice_t::send_msg_t bytes;
|
||||
|
||||
AdcDeviceProtoMessage msg(bytes);
|
||||
msg.set(std::forward<AttrNameT>(attr_name), std::forward<ValueT>(value), std::forward<ValueTs>(values)...);
|
||||
using m_t = std::remove_cvref_t<decltype(msg)>;
|
||||
|
||||
// expected respond: ACK SET ATTR_NAME ATTR_VALUE
|
||||
// return ATTR_NAME ATTR_VALUE (or error description 'code category what')
|
||||
return _getFromServer<R>(m_t::SET_KEY, bytes, rtype);
|
||||
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_SET, rtype, std::forward<ValueT>(value),
|
||||
std::forward<ValueTs>(values)...);
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range AttrNameT, typename ValueT, typename... ValueTs>
|
||||
@@ -264,6 +240,23 @@ public:
|
||||
std::forward<ValueT>(value), std::forward<ValueTs>(values)...);
|
||||
}
|
||||
|
||||
// ADC device helper methods (asynchronous)
|
||||
|
||||
// get device names
|
||||
|
||||
template <std::convertible_to<async_callback_func_t> CallbackT>
|
||||
auto asyncDeviceNames(CallbackT&& callback_func)
|
||||
{
|
||||
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_NAMES,
|
||||
std::forward<CallbackT>(callback_func));
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range DevNameT, std::convertible_to<async_callback_func_t> CallbackT>
|
||||
auto asyncBindDevice(DevNameT&& dev_name, CallbackT&& callback_func)
|
||||
{
|
||||
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_DEVICE,
|
||||
std::forward<CallbackT>(callback_func), std::forward<DevNameT>(dev_name));
|
||||
}
|
||||
|
||||
protected:
|
||||
netsession_ident_t _ident;
|
||||
@@ -279,12 +272,10 @@ public:
|
||||
|
||||
// helper methods
|
||||
|
||||
|
||||
template <traits::adc_range_of_output_char_range R>
|
||||
R _getFromServer(std::string_view key, const typename netservice_t::send_msg_t& bytes, ServerResponseType& type)
|
||||
R checkServerRespond(std::string_view key, const auto& bytes, ServerResponseType& type) const
|
||||
{
|
||||
auto rbytes = sendRecv(bytes);
|
||||
AdcDeviceProtoMessage dev_msg(rbytes);
|
||||
AdcDeviceProtoMessage dev_msg(bytes);
|
||||
|
||||
if (!dev_msg.isValid()) {
|
||||
throw std::system_error(AdcDeviceNetClientSessionError::ERROR_INVALID_SERVER_RESPOND);
|
||||
@@ -301,32 +292,59 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _sendRecvCallbackWrapper(auto err,
|
||||
typename netservice_t::recv_msg_t msg,
|
||||
auto&& ack_func,
|
||||
auto&& error_func)
|
||||
template <traits::adc_range_of_output_char_range R>
|
||||
R getFromServer(std::string_view key, const typename netservice_t::send_msg_t& bytes, ServerResponseType& type)
|
||||
{
|
||||
if (err) {
|
||||
_clientPtr->logError("An error occured while receiving server respond: {}",
|
||||
netservice_t::formattableError(err));
|
||||
} else {
|
||||
AdcDeviceProtoMessage dev_msg(msg);
|
||||
auto rbytes = sendRecv(bytes);
|
||||
|
||||
if (!dev_msg.isValid()) {
|
||||
_clientPtr->logError("Invalid server respond");
|
||||
return;
|
||||
}
|
||||
return checkServerRespond<R>(key, rbytes, type);
|
||||
}
|
||||
|
||||
if (dev_msg.isACK()) {
|
||||
std::forward<decltype(ack_func)>(ack_func)(dev_msg.attrs());
|
||||
} else if (dev_msg.isERROR()) {
|
||||
std::forward<decltype(error_func)>(error_func)(dev_msg.attrs());
|
||||
template <traits::adc_range_of_output_char_range R, typename... ArgTs>
|
||||
R deviceFuncHelper(std::string_view key, ServerResponseType& rtype, ArgTs&&... args)
|
||||
{
|
||||
typename netservice_t::send_msg_t bytes;
|
||||
|
||||
AdcDeviceProtoMessage msg(bytes);
|
||||
msg.setKeyValue(key, std::forward<ArgTs>(args)...);
|
||||
|
||||
return getFromServer<R>(key, bytes, rtype);
|
||||
}
|
||||
|
||||
|
||||
template <std::convertible_to<async_callback_func_t> CallbackT, typename... ArgTs>
|
||||
auto asyncDeviceFuncHelper(std::string_view key, CallbackT&& callback_func, ArgTs&&... args)
|
||||
{
|
||||
auto bytes = std::shared_ptr<typename netservice_t::send_msg_t>();
|
||||
|
||||
AdcDeviceProtoMessage msg(*bytes);
|
||||
msg.setKeyValue(key, std::forward<ArgTs>(args)...);
|
||||
|
||||
asyncSendRecv(*bytes, [bytes, key, wrapper = traits::adc_pf_wrapper(std::forward<CallbackT>(callback_func)),
|
||||
this](auto err, auto rmsg) mutable {
|
||||
if (err) {
|
||||
_clientPtr->logError("An error occured while receiving server respond: {}",
|
||||
netservice_t::formattableError(err));
|
||||
} else {
|
||||
_clientPtr->logError("Unexpectable server respond (msg key: {})", dev_msg.key());
|
||||
try {
|
||||
ServerResponseType type;
|
||||
auto attrs = checkServerRespond<default_server_resp_t>(key, rmsg, type);
|
||||
|
||||
std::forward<CallbackT>(std::get<0>(wrapper))(type, attrs);
|
||||
|
||||
} catch (const std::system_error& err) {
|
||||
_clientPtr->logError("An error occured while getting server respond: {}", err.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range SendMsgT>
|
||||
auto sendRecv(const SendMsgT& send_msg)
|
||||
{
|
||||
_netService.send(send_msg, _sendTimeout);
|
||||
return _netService.receive(_recvTimeout);
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range SendMsgT, typename TokenT>
|
||||
auto asyncSendRecv(const SendMsgT& send_msg, TokenT&& token)
|
||||
@@ -344,13 +362,6 @@ public:
|
||||
_sendTimeout);
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range SendMsgT>
|
||||
auto sendRecv(const SendMsgT& send_msg)
|
||||
{
|
||||
_netService.send(send_msg, _sendTimeout);
|
||||
return _netService.receive(_recvTimeout);
|
||||
}
|
||||
|
||||
}; // end of 'Session' class declaration
|
||||
|
||||
using base_t::base_t;
|
||||
|
||||
Reference in New Issue
Block a user