...
This commit is contained in:
85
net/asio/adc_device_netserver_asio.h
Normal file
85
net/asio/adc_device_netserver_asio.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include <asio/io_context.hpp>
|
||||
#include <asio/ip/tcp.hpp>
|
||||
#include <asio/ip/udp.hpp>
|
||||
#include <asio/local/seq_packet_protocol.hpp>
|
||||
#include <asio/local/stream_protocol.hpp>
|
||||
|
||||
#include "../adc_device_netserver.h"
|
||||
#include "../adc_endpoint.h"
|
||||
#include "adc_netservice_asio.h"
|
||||
|
||||
namespace adc::impl
|
||||
{
|
||||
|
||||
class AdcDeviceNetServerASIO : public AdcDeviceNetServer
|
||||
{
|
||||
public:
|
||||
template <traits::adc_input_char_range R>
|
||||
AdcDeviceNetServerASIO(const R& id, asio::io_context& io_context) : AdcDeviceNetServer(id), _ioContext(io_context)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template <interfaces::adc_netsession_proto_c SessProtoT, std::derived_from<AdcEndpointParser> EptT>
|
||||
void start(const EptT& endpoint)
|
||||
{
|
||||
if (!endpoint.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// may thow here!
|
||||
#ifdef USE_OPENSSL_WITH_ASIO
|
||||
if (endpoint.isTCP() || endpoint.isTLS()) {
|
||||
asio::ip::tcp::endpoint ept(asio::ip::make_address(endpoint.host()), endpoint.port());
|
||||
if (endpoint.isTCP()) {
|
||||
using srv_t = AdcNetServiceASIOBase<asio::ip::tcp, SessProtoT>;
|
||||
AdcDeviceNetServer::start<Session<srv_t>>("TCP", this, _ioContext, ept);
|
||||
} else {
|
||||
}
|
||||
#else
|
||||
if (endpoint.isTCP()) {
|
||||
asio::ip::tcp::endpoint ept(asio::ip::make_address(endpoint.host()), endpoint.port());
|
||||
using srv_t = AdcNetServiceASIOBase<asio::ip::tcp, AdcStopSeqSessionProto<>>;
|
||||
AdcDeviceNetServer::start<Session<srv_t>>("TCP", this, _ioContext, ept);
|
||||
#endif
|
||||
} else if (endpoint.isLocal()) {
|
||||
if (endpoint.isLocalStream()) {
|
||||
asio::local::stream_protocol::endpoint ept(endpoint.template path<std::string>());
|
||||
using srv_t = AdcNetServiceASIOBase<asio::local::stream_protocol, SessProtoT>;
|
||||
AdcDeviceNetServer::start<Session<srv_t>>("LOCAL STREAM", this, _ioContext, ept);
|
||||
} else if (endpoint.isLocalDatagram()) {
|
||||
asio::local::datagram_protocol::endpoint ept(endpoint.template path<std::string>());
|
||||
using srv_t = AdcNetServiceASIOBase<asio::local::datagram_protocol, SessProtoT>;
|
||||
AdcDeviceNetServer::start<Session<srv_t>>("LOCAL DGRAM", this, _ioContext, ept);
|
||||
} else if (endpoint.isLocalSeqpacket()) {
|
||||
asio::local::seq_packet_protocol::endpoint ept(endpoint.template path<std::string>());
|
||||
using srv_t = AdcNetServiceASIOBase<asio::local::seq_packet_protocol, SessProtoT>;
|
||||
AdcDeviceNetServer::start<Session<srv_t>>("LOCAL SEQPACK", this, _ioContext, ept);
|
||||
}
|
||||
} else {
|
||||
throw std::system_error(std::make_error_code(std::errc::protocol_not_supported));
|
||||
}
|
||||
}
|
||||
|
||||
// some default endpoint?!!
|
||||
void start() {}
|
||||
|
||||
protected:
|
||||
asio::io_context& _ioContext;
|
||||
|
||||
// demonizing ASIO-related methods
|
||||
virtual void daemonizePrepare()
|
||||
{
|
||||
_ioContext.notify_fork(asio::execution_context::fork_prepare);
|
||||
}
|
||||
|
||||
virtual void daemonizeFinalize()
|
||||
{
|
||||
_ioContext.notify_fork(asio::io_context::fork_child);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace adc::impl
|
||||
@@ -161,9 +161,11 @@ public:
|
||||
typedef AdcNetServiceASIOBase netservice_t;
|
||||
typedef std::shared_ptr<netservice_t> sptr_netservice_t;
|
||||
|
||||
typedef std::function<void(std::error_code, sptr_netservice_t)> async_accept_callback_t;
|
||||
typedef std::function<void(std::error_code, netservice_t)> async_accept_callback_t;
|
||||
// typedef std::function<void(std::error_code, sptr_netservice_t)> async_accept_callback_t;
|
||||
|
||||
template <asio::completion_token_for<void(std::error_code, sptr_netservice_t)> TokenT,
|
||||
// template <asio::completion_token_for<void(std::error_code, sptr_netservice_t)> TokenT,
|
||||
template <asio::completion_token_for<void(std::error_code, netservice_t)> TokenT,
|
||||
traits::adc_time_duration_c DT = decltype(DEFAULT_ACCEPT_TIMEOUT)>
|
||||
auto asyncAccept(TokenT&& token, const DT& timeout = DEFAULT_ACCEPT_TIMEOUT)
|
||||
{
|
||||
@@ -175,7 +177,8 @@ public:
|
||||
_socket = AdcNetServiceASIOBase::socket_t{_ioContext};
|
||||
auto timer = getDeadlineTimer(_acceptor, timeout);
|
||||
|
||||
return asio::async_compose<TokenT, void(std::error_code, sptr_netservice_t)>(
|
||||
// return asio::async_compose<TokenT, void(std::error_code, sptr_netservice_t)>(
|
||||
return asio::async_compose<TokenT, void(std::error_code, netservice_t)>(
|
||||
[timer = std::move(timer), start = true, this](auto& self, std::error_code ec = {}) mutable {
|
||||
if (!ec) {
|
||||
if (start) {
|
||||
@@ -186,7 +189,8 @@ public:
|
||||
}
|
||||
} catch (std::system_error err) {
|
||||
timer->cancel();
|
||||
self.complete(err.code(), std::make_shared<netservice_t>(_ioContext));
|
||||
self.complete(err.code(), netservice_t{_ioContext});
|
||||
// self.complete(err.code(), std::make_shared<netservice_t>(_ioContext));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -200,13 +204,13 @@ public:
|
||||
timer->cancel();
|
||||
}
|
||||
|
||||
// self.complete(ec, AdcNetServiceASIOBase(std::move(_socket)));
|
||||
self.complete(ec, std::make_shared<netservice_t>(std::move(_socket)));
|
||||
self.complete(ec, netservice_t(std::move(_socket)));
|
||||
// self.complete(ec, std::make_shared<netservice_t>(std::move(_socket)));
|
||||
},
|
||||
token, _ioContext);
|
||||
}
|
||||
|
||||
template <asio::completion_token_for<void(std::error_code, AdcNetServiceASIOBase)> TokenT,
|
||||
template <asio::completion_token_for<void(std::error_code, netservice_t)> TokenT,
|
||||
traits::adc_time_duration_c DT = decltype(DEFAULT_ACCEPT_TIMEOUT)>
|
||||
auto asyncAccept(const AdcNetServiceASIOBase::endpoint_t& endpoint,
|
||||
TokenT&& token,
|
||||
|
||||
Reference in New Issue
Block a user