...
This commit is contained in:
parent
ebe93f1d74
commit
9f915d932f
@ -44,6 +44,36 @@ concept adc_netserver_session_impl_c = requires(T t, const T t_const) {
|
|||||||
|
|
||||||
/* Server session */
|
/* Server session */
|
||||||
|
|
||||||
|
class AdcNetServerGenericSession
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Opt {
|
||||||
|
std::function<void()> startSess;
|
||||||
|
std::function<void()> stopSess;
|
||||||
|
std::function<void()> run;
|
||||||
|
};
|
||||||
|
|
||||||
|
AdcNetServerGenericSession(Opt&& opts) : _opts(std::move(opts)) {}
|
||||||
|
|
||||||
|
virtual void start()
|
||||||
|
{
|
||||||
|
_opts.startSess();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void stop()
|
||||||
|
{
|
||||||
|
_opts.stopSess();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Opt _opts;
|
||||||
|
|
||||||
|
virtual void run()
|
||||||
|
{
|
||||||
|
_opts.run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <traits::adc_netserver_session_impl_c ImplT>
|
template <traits::adc_netserver_session_impl_c ImplT>
|
||||||
class AdcNetServerSession : std::enable_shared_from_this<AdcNetServerSession<ImplT>>
|
class AdcNetServerSession : std::enable_shared_from_this<AdcNetServerSession<ImplT>>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -44,15 +44,26 @@
|
|||||||
namespace adc::traits
|
namespace adc::traits
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// typedef for ASIO streambuf iterators
|
||||||
|
using asio_streambuff_iter_t = asio::buffers_iterator<asio::streambuf::const_buffers_type>;
|
||||||
|
|
||||||
// still only TCP, UDP and UNIX
|
// still only TCP, UDP and UNIX
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept adc_asio_inet_proto_c =
|
concept adc_asio_inet_proto_c = requires(T t, asio_streambuff_iter_t begin, asio_streambuff_iter_t end) {
|
||||||
std::derived_from<T, asio::ip::tcp> || std::derived_from<T, asio::ip::udp> ||
|
std::derived_from<T, asio::ip::tcp> || std::derived_from<T, asio::ip::udp> ||
|
||||||
std::derived_from<T, asio::local::seq_packet_protocol> || std::derived_from<T, asio::local::stream_protocol>;
|
std::derived_from<T, asio::local::seq_packet_protocol> || std::derived_from<T, asio::local::stream_protocol>;
|
||||||
|
{ t.matchCondition(begin, end) } -> std::same_as<std::pair<asio_streambuff_iter_t, bool>>;
|
||||||
|
{ t.fromLowLevel(begin, end) } -> std::same_as<std::pair<asio_streambuff_iter_t, bool>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// only stream-based protocols
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept adc_asio_inet_stream_proto_c =
|
concept adc_asio_inet_stream_proto_c = requires(T t, asio_streambuff_iter_t begin, asio_streambuff_iter_t end) {
|
||||||
std::derived_from<T, asio::ip::tcp> || std::derived_from<T, asio::local::stream_protocol>;
|
std::derived_from<T, asio::ip::tcp> || std::derived_from<T, asio::local::stream_protocol>;
|
||||||
|
{ t.matchCondition(begin, end) } -> std::same_as<std::pair<asio_streambuff_iter_t, bool>>;
|
||||||
|
{ t.fromLowLevel(begin, end) } -> std::same_as<std::pair<asio_streambuff_iter_t, bool>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace adc::traits
|
} // namespace adc::traits
|
||||||
|
|
||||||
@ -77,14 +88,16 @@ public:
|
|||||||
typedef std::chrono::steady_clock::duration timeout_t; // nanoseconds resolution
|
typedef std::chrono::steady_clock::duration timeout_t; // nanoseconds resolution
|
||||||
|
|
||||||
|
|
||||||
using streambuff_iter_t = asio::buffers_iterator<asio::streambuf::const_buffers_type>;
|
|
||||||
|
|
||||||
AdcNetServiceASIO(asio::io_context& io_context) : _ioContext(io_context), _socket(io_context), _acceptor(io_context)
|
AdcNetServiceASIO(asio::io_context& io_context) : _ioContext(io_context), _socket(io_context), _acceptor(io_context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~AdcNetServiceASIO() = default;
|
virtual ~AdcNetServiceASIO() = default;
|
||||||
|
|
||||||
|
const asio::io_context& getExecutor() const
|
||||||
|
{
|
||||||
|
return _ioContext;
|
||||||
|
}
|
||||||
|
|
||||||
template <traits::adc_time_duration_c TimeoutT, asio::completion_token_for<void(std::error_code)> CompletionTokenT>
|
template <traits::adc_time_duration_c TimeoutT, asio::completion_token_for<void(std::error_code)> CompletionTokenT>
|
||||||
auto asyncAccept(const endpoint_t& endpoint, const TimeoutT& timeout, CompletionTokenT&& token)
|
auto asyncAccept(const endpoint_t& endpoint, const TimeoutT& timeout, CompletionTokenT&& token)
|
||||||
@ -210,7 +223,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <traits::adc_netmessage_c NetMessageT, traits::adc_time_duration_c TimeoutT, typename CompletionTokenT>
|
template <traits::adc_netmessage_c NetMessageT,
|
||||||
|
traits::adc_time_duration_c TimeoutT,
|
||||||
|
asio::completion_token_for<void(std::error_code, const NetMessageT&)> CompletionTokenT>
|
||||||
auto asyncReceive(const TimeoutT& timeout, CompletionTokenT&& token)
|
auto asyncReceive(const TimeoutT& timeout, CompletionTokenT&& token)
|
||||||
{
|
{
|
||||||
enum { starting, finishing };
|
enum { starting, finishing };
|
||||||
@ -251,7 +266,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto begin_it = streambuff_iter_t::begin(_streamBuffer.data());
|
auto begin_it = traits::asio_streambuff_iter_t::begin(_streamBuffer.data());
|
||||||
auto end_it = begin_it + _streamBuffer.data().size();
|
auto end_it = begin_it + _streamBuffer.data().size();
|
||||||
|
|
||||||
// check for byte sequence is valid byte sequence and find the limits
|
// check for byte sequence is valid byte sequence and find the limits
|
||||||
@ -368,7 +383,7 @@ public:
|
|||||||
typedef std::function<int(const std::string& serial, const std::vector<unsigned char>& fingerprint, int depth)>
|
typedef std::function<int(const std::string& serial, const std::vector<unsigned char>& fingerprint, int depth)>
|
||||||
cert_comp_func_t;
|
cert_comp_func_t;
|
||||||
|
|
||||||
using streambuff_iter_t = asio::buffers_iterator<asio::streambuf::const_buffers_type>;
|
using asio_streambuff_iter_t = asio::buffers_iterator<asio::streambuf::const_buffers_type>;
|
||||||
|
|
||||||
AdcNetServiceAsioTls(asio::io_context& io_context,
|
AdcNetServiceAsioTls(asio::io_context& io_context,
|
||||||
asio::ssl::context&& tls_context = asio::ssl::context(asio::ssl::context::tlsv13),
|
asio::ssl::context&& tls_context = asio::ssl::context(asio::ssl::context::tlsv13),
|
||||||
@ -540,7 +555,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto begin_it = streambuff_iter_t::begin(_streamBuffer.data());
|
auto begin_it = asio_streambuff_iter_t::begin(_streamBuffer.data());
|
||||||
auto end_it = begin_it + _streamBuffer.data().size();
|
auto end_it = begin_it + _streamBuffer.data().size();
|
||||||
|
|
||||||
// check for byte sequence is valid byte sequence and find the limits
|
// check for byte sequence is valid byte sequence and find the limits
|
||||||
@ -708,10 +723,10 @@ protected:
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef AdcNetService<impl::AdcNetServiceASIO<asio::ip::tcp>> AdcNetServiceAsioTcp;
|
// typedef AdcNetService<impl::AdcNetServiceASIO<asio::ip::tcp>> AdcNetServiceAsioTcp;
|
||||||
typedef AdcNetService<impl::AdcNetServiceASIO<asio::ip::udp>> AdcNetServiceAsioUdp;
|
// typedef AdcNetService<impl::AdcNetServiceASIO<asio::ip::udp>> AdcNetServiceAsioUdp;
|
||||||
typedef AdcNetService<impl::AdcNetServiceASIO<asio::local::seq_packet_protocol>> AdcNetServiceAsioLocalSeqPack;
|
// typedef AdcNetService<impl::AdcNetServiceASIO<asio::local::seq_packet_protocol>> AdcNetServiceAsioLocalSeqPack;
|
||||||
typedef AdcNetService<impl::AdcNetServiceASIO<asio::local::stream_protocol>> AdcNetServiceAsioLocalStream;
|
// typedef AdcNetService<impl::AdcNetServiceASIO<asio::local::stream_protocol>> AdcNetServiceAsioLocalStream;
|
||||||
|
|
||||||
} // namespace adc::impl
|
} // namespace adc::impl
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ namespace adc::impl
|
|||||||
{
|
{
|
||||||
|
|
||||||
template <traits::adc_netservice_asio_c NetServiceT, typename ContextT = std::nullptr_t>
|
template <traits::adc_netservice_asio_c NetServiceT, typename ContextT = std::nullptr_t>
|
||||||
class AdcNetServerSessionASIO
|
class AdcNetServerSessionASIO : std::enable_shared_from_this<AdcNetServerSessionASIO<NetServiceT, ContextT>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::string_view session_ident_t;
|
typedef std::string_view session_ident_t;
|
||||||
@ -32,24 +32,43 @@ public:
|
|||||||
|
|
||||||
typedef std::chrono::duration<double, std::milli> timeout_t;
|
typedef std::chrono::duration<double, std::milli> timeout_t;
|
||||||
|
|
||||||
static constexpr timeout_t defaultSendTimeout = std::chrono::milliseconds(5000);
|
static constexpr timeout_t defaultSendTimeout = std::chrono::milliseconds(5000); // 5 seconds
|
||||||
static constexpr timeout_t defaultRecvTimeout = std::chrono::milliseconds(5000);
|
static constexpr timeout_t defaultRecvTimeout =
|
||||||
|
std::chrono::hours(12); // actualy, it is a time to wait something from client
|
||||||
|
|
||||||
template <traits::adc_input_char_range R>
|
template <traits::adc_input_char_range R>
|
||||||
AdcNetServerSessionASIO(netservice_t::socket_t&& sock, const R& sess_ident, ContextT&& context = nullptr)
|
AdcNetServerSessionASIO(std::shared_ptr<netservice_t>& net_service,
|
||||||
: _socket(std::move(sock)),
|
const R& sess_ident,
|
||||||
|
ContextT&& context = nullptr)
|
||||||
|
: _socket(net_service.get_executor()),
|
||||||
|
// _socket(std::move(sock)),
|
||||||
_netService(_socket),
|
_netService(_socket),
|
||||||
_sessionIdent(sess_ident.begin(), sess_ident.end()),
|
_sessionIdent(sess_ident.begin(), sess_ident.end()),
|
||||||
_context(context),
|
_context(context),
|
||||||
_sendTimeout(defaultSendTimeout),
|
_sendTimeout(defaultSendTimeout),
|
||||||
_recvTimeout(defaultRecvTimeout)
|
_recvTimeout(defaultRecvTimeout)
|
||||||
{
|
{
|
||||||
|
// generic implementation
|
||||||
|
_stopFunc = [net_service = net_service]() { net_service->close(); };
|
||||||
|
|
||||||
|
_startFunc = [this]() { acceptMessage(); };
|
||||||
|
|
||||||
|
_acceptMessageFunc = [net_service = net_service, this]() {
|
||||||
|
net_service->asynReceive<NetMessageT>(
|
||||||
|
_recvTimeout, [self = this->shared_from_this(), this](std::error_code ec, const auto& mess) {
|
||||||
|
if (ec) {
|
||||||
|
stop();
|
||||||
|
} else {
|
||||||
|
acceptMessage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual ~AdcNetServerSessionASIO()
|
virtual ~AdcNetServerSessionASIO()
|
||||||
{
|
{
|
||||||
_netService.close();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_time_duration_c TimeoutT>
|
template <traits::adc_time_duration_c TimeoutT>
|
||||||
@ -68,10 +87,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void start() {}
|
virtual void start()
|
||||||
|
{
|
||||||
|
_startFunc();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void stop() {}
|
virtual void stop()
|
||||||
|
{
|
||||||
|
_stopFunc();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
netservice_t::socket_t _socket;
|
netservice_t::socket_t _socket;
|
||||||
@ -81,6 +106,13 @@ protected:
|
|||||||
ContextT _context;
|
ContextT _context;
|
||||||
|
|
||||||
timeout_t _sendTimeout, _recvTimeout;
|
timeout_t _sendTimeout, _recvTimeout;
|
||||||
|
|
||||||
|
std::function<void()> _startFunc, _stopFunc, _acceptMessageFunc;
|
||||||
|
|
||||||
|
virtual void acceptMessage()
|
||||||
|
{
|
||||||
|
_acceptMessageFunc();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace adc::impl
|
} // namespace adc::impl
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user