...
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "../concepts/snplib_concepts.h"
|
#include "../concepts/snplib_concepts.h"
|
||||||
#include "../containers/snplib_hvec.h"
|
|
||||||
|
|
||||||
namespace snplib
|
namespace snplib
|
||||||
{
|
{
|
||||||
@@ -23,6 +22,21 @@ concept snplib_net_endpoint_c = requires(T t, const T t_const) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept snplib_net_message_c = requires(T t) {
|
||||||
|
{ t.toBytes() } -> snplib_output_char_range_c;
|
||||||
|
|
||||||
|
// can be constructed from contiguous byte range
|
||||||
|
requires(
|
||||||
|
requires {
|
||||||
|
{ T::fromBytes(std::declval<std::span<const char>>()) } -> std::same_as<T>;
|
||||||
|
} ||
|
||||||
|
requires {
|
||||||
|
{ T::fromBytes(std::declval<std::span<char>>()) } -> std::same_as<T>;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept snplib_net_connection_c = requires(T t) {
|
concept snplib_net_connection_c = requires(T t) {
|
||||||
// static constexpr member
|
// static constexpr member
|
||||||
@@ -46,7 +60,8 @@ concept snplib_net_session_c = std::derived_from<T, std::enable_shared_from_this
|
|||||||
|
|
||||||
snplib_net_connection_c<typename T::connection_t>;
|
snplib_net_connection_c<typename T::connection_t>;
|
||||||
|
|
||||||
{ t.startSession(std::declval<typename T::connection_t>()) } -> snplib_async_retval_c;
|
// { t.startSession(std::declval<typename T::connection_t>()) } -> snplib_async_retval_c;
|
||||||
|
t.startSession(std::declval<typename T::connection_t>());
|
||||||
|
|
||||||
t.stopSession();
|
t.stopSession();
|
||||||
};
|
};
|
||||||
@@ -58,73 +73,67 @@ concept snplib_net_listener_c = requires(T t) {
|
|||||||
std::formattable<decltype(T::id), char>;
|
std::formattable<decltype(T::id), char>;
|
||||||
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
||||||
|
|
||||||
snplib_net_session_c<typename T::session_t>;
|
snplib_net_connection_c<typename T::connection_t>;
|
||||||
|
|
||||||
{ t.accept() } -> snplib_async_retval_c<typename T::session_t>;
|
{ t.accept() } -> snplib_async_retval_c<typename T::connection_t>;
|
||||||
|
|
||||||
// { t.accept() } -> snplib_expected_c; // must return std::expected<snplib_net_session_c, snplib_error_c>
|
{ t.startListen() } -> snplib_error_c;
|
||||||
|
|
||||||
// snplib_net_session_c<typename std::invoke_result_t<decltype(t.accept)>::value_type>;
|
t.stopListen();
|
||||||
|
|
||||||
{ t.start() } -> snplib_error_c;
|
|
||||||
|
|
||||||
t.stop();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct snplib_netserver_iface_t {
|
|
||||||
virtual ~snplib_netserver_iface_t() = default;
|
|
||||||
|
|
||||||
template <std::derived_from<snplib_netserver_iface_t> SelfT, snplib_net_listener_c LT>
|
|
||||||
auto start(this SelfT&& self, LT&& listener)
|
|
||||||
{
|
|
||||||
return std::forward<SelfT>(self).start(std::forward<LT>(listener));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
snplib_netserver_iface_t() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept snplib_netserver_c = std::derived_from<T, snplib_netserver_iface_t> && requires(T t) {
|
concept snplib_netserver_c = requires(T t) {
|
||||||
// static constexpr member
|
// static constexpr member
|
||||||
std::formattable<decltype(T::id), char>;
|
std::formattable<decltype(T::id), char>;
|
||||||
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
||||||
|
|
||||||
|
|
||||||
// start/stop all listeners
|
// start/stop all listeners
|
||||||
{ t.start() } -> snplib_error_c;
|
t.startServer();
|
||||||
|
|
||||||
{ t.stop() } -> snplib_error_c;
|
t.stopServer();
|
||||||
|
|
||||||
{ t.disconnectClients() } -> snplib_error_c;
|
t.disconnectClients();
|
||||||
|
// { t.startServer() } -> snplib_error_c;
|
||||||
|
|
||||||
|
// { t.stopServer() } -> snplib_error_c;
|
||||||
|
|
||||||
|
// { t.disconnectClients() } -> snplib_error_c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* SINGLE-PROTO*/
|
/* SINGLE-PROTO*/
|
||||||
|
|
||||||
template <snplib_net_listener_c ListenerT>
|
template <snplib_net_listener_c ListenerT, snplib_net_session_c SessionT>
|
||||||
|
requires std::same_as<typename ListenerT::connection_t, typename SessionT::connection_t>
|
||||||
class snplib_generic_netserver_t
|
class snplib_generic_netserver_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::error_code error_t;
|
// typedef std::error_code error_t;
|
||||||
|
|
||||||
using session_t = typename ListenerT::session_t;
|
|
||||||
|
|
||||||
snplib_generic_netserver_t(std::unique_ptr<ListenerT> listener) : _listener(std::move(listener)) {}
|
snplib_generic_netserver_t(std::unique_ptr<ListenerT> listener) : _listener(std::move(listener)) {}
|
||||||
|
|
||||||
error_t start()
|
auto startServer()
|
||||||
{
|
{
|
||||||
auto err = _listener->start();
|
auto err = _listener->start();
|
||||||
if (err) {
|
if (err) {
|
||||||
return snplib_deduced_error(err, std::make_error_code(std::errc::io_error));
|
co_return std::unexpect(snplib_deduced_error(err, std::make_error_code(std::errc::io_error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
startListen();
|
while (true) {
|
||||||
|
auto connection = co_await _listener->accept();
|
||||||
|
if (connection) {
|
||||||
|
auto sptr = std::make_shared<SessionT>();
|
||||||
|
_sessions.insert(sptr);
|
||||||
|
sptr->start(std::move(connection.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t stop()
|
error_t stopServer()
|
||||||
{
|
{
|
||||||
_listener->stop();
|
_listener->stop();
|
||||||
|
|
||||||
@@ -133,15 +142,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<ListenerT> _listener{};
|
std::unique_ptr<ListenerT> _listener{};
|
||||||
std::set<std::weak_ptr<session_t>> _sessions{};
|
std::set<std::weak_ptr<SessionT>> _sessions{};
|
||||||
|
|
||||||
void startListen()
|
|
||||||
{
|
|
||||||
auto sess = co_await _listener->accept();
|
|
||||||
if (sess) {
|
|
||||||
_sessions.insert(sess);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user