...
This commit is contained in:
parent
53a16d7571
commit
eba7ac39c9
@ -85,6 +85,10 @@ set(CNTR_PROTO_LIB_SRC
|
|||||||
set(CNTR_PROTO_LIB comm_proto)
|
set(CNTR_PROTO_LIB comm_proto)
|
||||||
add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC})
|
add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC})
|
||||||
|
|
||||||
|
set(MOUNT_SERVER_APP_SRC mount.h mount_server.cpp comm_server.h)
|
||||||
|
set(MOUNT_SERVER_APP mount_server)
|
||||||
|
add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC})
|
||||||
|
target_link_libraries(${MOUNT_SERVER_APP} ${CNTR_PROTO_LIB} spdlog::spdlog_header_only)
|
||||||
|
|
||||||
if (WITH_TESTS)
|
if (WITH_TESTS)
|
||||||
set(CNTR_PROTO_TEST_APP cntr_proto_test)
|
set(CNTR_PROTO_TEST_APP cntr_proto_test)
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include <asio/streambuf.hpp>
|
#include <asio/streambuf.hpp>
|
||||||
#include <asio/write.hpp>
|
#include <asio/write.hpp>
|
||||||
|
|
||||||
|
#include <spdlog/sinks/null_sink.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include "comm_server_endpoint.h"
|
#include "comm_server_endpoint.h"
|
||||||
@ -75,7 +76,7 @@ public:
|
|||||||
static constexpr std::chrono::duration DEFAULT_RCV_TIMEOUT = std::chrono::hours(12);
|
static constexpr std::chrono::duration DEFAULT_RCV_TIMEOUT = std::chrono::hours(12);
|
||||||
static constexpr std::chrono::duration DEFAULT_SND_TIMEOUT = std::chrono::milliseconds(2000);
|
static constexpr std::chrono::duration DEFAULT_SND_TIMEOUT = std::chrono::milliseconds(2000);
|
||||||
|
|
||||||
MccMountServer(asio::io_context& ctx, std::shared_ptr<spdlog::logger> logger)
|
MccMountServer(asio::io_context& ctx, std::shared_ptr<spdlog::logger> logger = spdlog::null_logger_mt("NULL"))
|
||||||
: _asioContext(ctx), _serverLogger(std::move(logger))
|
: _asioContext(ctx), _serverLogger(std::move(logger))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -84,21 +85,18 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
template <typename... CtorArgTs>
|
template <typename... CtorArgTs>
|
||||||
asio::awaitable<bool> listen(std::derived_from<MccServerEndpoint> auto endpoint, CtorArgTs&&... ctor_args)
|
asio::awaitable<void> listen(std::derived_from<MccServerEndpoint> auto endpoint, CtorArgTs&&... ctor_args)
|
||||||
{
|
{
|
||||||
bool exit_flag = false;
|
|
||||||
|
|
||||||
if (!endpoint.isValid()) {
|
if (!endpoint.isValid()) {
|
||||||
_serverLogger->error("Cannot start listening! Invalid endpoint string representation ('{}')!",
|
_serverLogger->error("Cannot start listening! Invalid endpoint string representation ('{}')!",
|
||||||
endpoint.endpoint());
|
endpoint.endpoint());
|
||||||
co_return exit_flag;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add root path to endpoint one
|
// add root path to endpoint one
|
||||||
std::filesystem::path pt("/");
|
std::filesystem::path pt("/");
|
||||||
pt += endpoint.path();
|
pt += endpoint.path();
|
||||||
|
|
||||||
auto args = std::make_tuple(std::forward<CtorArgTs>(ctor_args)...);
|
|
||||||
|
|
||||||
if (endpoint.isLocalSerial()) {
|
if (endpoint.isLocalSerial()) {
|
||||||
asio::serial_port s_port(_asioContext);
|
asio::serial_port s_port(_asioContext);
|
||||||
@ -112,26 +110,26 @@ public:
|
|||||||
s_port.open(pt.string(), ec);
|
s_port.open(pt.string(), ec);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
_serverLogger->error("Cannot open serial device '{}' (Error = '{}')!", pt.string(), ec.message());
|
_serverLogger->error("Cannot open serial device '{}' (Error = '{}')!", pt.string(), ec.message());
|
||||||
co_return exit_flag;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// asio::co_spawn(_asioContext, listen(std::move(s_port)), asio::detached);
|
// asio::co_spawn(_asioContext, listen(std::move(s_port)), asio::detached);
|
||||||
co_return listen(std::move(s_port));
|
co_await listen(std::move(s_port));
|
||||||
} else if (endpoint.isLocal()) {
|
} else if (endpoint.isLocal()) {
|
||||||
// create abstract namespace socket endpoint if its path starts from '@' symbol
|
// create abstract namespace socket endpoint if its path starts from '@' symbol
|
||||||
endpoint.makeAbstract('@');
|
endpoint.makeAbstract('@');
|
||||||
|
|
||||||
|
|
||||||
if (endpoint.isLocalStream()) {
|
if (endpoint.isLocalStream()) {
|
||||||
co_return listen(asio::local::stream_protocol::endpoint(pt.string()));
|
co_await listen(asio::local::stream_protocol::endpoint(pt.string()));
|
||||||
// asio::co_spawn(_asioContext, listen(asio::local::stream_protocol::endpoint(pt.string())),
|
// asio::co_spawn(_asioContext, listen(asio::local::stream_protocol::endpoint(pt.string())),
|
||||||
// asio::detached);
|
// asio::detached);
|
||||||
} else if (endpoint.isLocalSeqpacket()) {
|
} else if (endpoint.isLocalSeqpacket()) {
|
||||||
co_return listen(asio::local::seq_packet_protocol::endpoint(pt.string()));
|
co_await listen(asio::local::seq_packet_protocol::endpoint(pt.string()));
|
||||||
// asio::co_spawn(_asioContext, listen(asio::local::seq_packet_protocol::endpoint(pt.string())),
|
// asio::co_spawn(_asioContext, listen(asio::local::seq_packet_protocol::endpoint(pt.string())),
|
||||||
// asio::detached);
|
// asio::detached);
|
||||||
} else {
|
} else {
|
||||||
co_return exit_flag; // ???!!!!
|
co_return; // it must not be!!!!
|
||||||
}
|
}
|
||||||
} else if (endpoint.isTCP()) {
|
} else if (endpoint.isTCP()) {
|
||||||
// resolve hostname
|
// resolve hostname
|
||||||
@ -140,27 +138,49 @@ public:
|
|||||||
|
|
||||||
auto r_result = co_await res.async_resolve(endpoint.host(), endpoint.portView(), asio::use_awaitable);
|
auto r_result = co_await res.async_resolve(endpoint.host(), endpoint.portView(), asio::use_awaitable);
|
||||||
|
|
||||||
|
_serverLogger->info("Resolve hostname <{}> to {} IP-addresses", endpoint.host(), r_result.size());
|
||||||
|
|
||||||
|
|
||||||
|
bool exit_flag = false;
|
||||||
|
asio::ip::tcp::acceptor acc(_asioContext);
|
||||||
|
|
||||||
for (auto const& epn : r_result) {
|
for (auto const& epn : r_result) {
|
||||||
exit_flag = co_await listen(epn);
|
try {
|
||||||
if (exit_flag) {
|
// std::stringstream st;
|
||||||
|
|
||||||
|
_serverLogger->debug("Create connection acceptor for endpoint <{}> ...",
|
||||||
|
epn.address().to_string());
|
||||||
|
acc = asio::ip::tcp::acceptor(_asioContext, epn);
|
||||||
|
// st << acc.local_endpoint();
|
||||||
|
exit_flag = true;
|
||||||
break;
|
break;
|
||||||
|
} catch (const std::system_error& err) {
|
||||||
|
_serverLogger->error("An error occuring while creating connection acceptor (ec = {})",
|
||||||
|
err.what());
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!exit_flag) {
|
if (!exit_flag) {
|
||||||
_serverLogger->error("Cannot start listening on any resolved endpoints!");
|
_serverLogger->error("Cannot start listening on any resolved endpoints!");
|
||||||
co_return exit_flag;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// listen(std::move(*r_result.begin()));
|
_tcpAcceptors.emplace_back(&acc);
|
||||||
|
|
||||||
|
_serverLogger->info("Start listening at <{}> endpoint ...", acc.local_endpoint().address().to_string());
|
||||||
|
|
||||||
|
// start accepting connections
|
||||||
|
for (;;) {
|
||||||
|
auto sock = co_await acc.async_accept(asio::use_awaitable);
|
||||||
|
// start new client session
|
||||||
|
asio::co_spawn(_asioContext, startSession(std::move(sock)), asio::detached);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (const std::system_error& err) {
|
} catch (const std::system_error& err) {
|
||||||
_serverLogger->error("An error occured while resolving '{}' hostname (Error = '{}')", endpoint.host(),
|
_serverLogger->error("An error occured while trying to start accepting connections! ec = '{}'",
|
||||||
err.code().message());
|
err.what());
|
||||||
co_return exit_flag;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
co_return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::mcc_endpoint_c EpnT>
|
template <traits::mcc_endpoint_c EpnT>
|
||||||
@ -186,10 +206,14 @@ public:
|
|||||||
try {
|
try {
|
||||||
std::stringstream st;
|
std::stringstream st;
|
||||||
|
|
||||||
_serverLogger->debug("Create connection acceptor ...");
|
st << endpoint;
|
||||||
|
_serverLogger->debug("Create connection acceptor for endpoint <{}> ...", st.str());
|
||||||
auto acc = epn_t::protocol_type::acceptor(_asioContext, endpoint);
|
auto acc = epn_t::protocol_type::acceptor(_asioContext, endpoint);
|
||||||
|
|
||||||
|
st.str("");
|
||||||
st << acc.local_endpoint();
|
st << acc.local_endpoint();
|
||||||
_serverLogger->info("Try to start listening at <{}> endpoint ...", st.str());
|
_serverLogger->info("Start listening at <{}> endpoint ...", st.str());
|
||||||
|
|
||||||
|
|
||||||
if constexpr (traits::is_tcp_proto<epn_t>) {
|
if constexpr (traits::is_tcp_proto<epn_t>) {
|
||||||
_tcpAcceptors.emplace_back(&acc);
|
_tcpAcceptors.emplace_back(&acc);
|
||||||
@ -315,7 +339,7 @@ private:
|
|||||||
|
|
||||||
std::vector<char> handleClientCommand(std::string_view command)
|
std::vector<char> handleClientCommand(std::string_view command)
|
||||||
{
|
{
|
||||||
std::vector<char> resp;
|
std::vector<char> resp{BM700::CONTROL_PROTO_STR_RESP_ACK.begin(), BM700::CONTROL_PROTO_STR_RESP_ACK.end()};
|
||||||
|
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
@ -353,13 +377,22 @@ private:
|
|||||||
asio::streambuf sbuff;
|
asio::streambuf sbuff;
|
||||||
size_t nbytes;
|
size_t nbytes;
|
||||||
std::stringstream st;
|
std::stringstream st;
|
||||||
|
std::string r_epn;
|
||||||
|
|
||||||
st << socket.remote_endpoint();
|
|
||||||
std::string r_epn = st.str();
|
|
||||||
|
|
||||||
st.str() = "";
|
|
||||||
st << std::this_thread::get_id();
|
st << std::this_thread::get_id();
|
||||||
std::string thr_id = st.str();
|
std::string thr_id = st.str();
|
||||||
|
st.str("");
|
||||||
|
|
||||||
|
if constexpr (traits::is_serial_proto<sock_t>) {
|
||||||
|
st << "serial port: " << socket.native_handle();
|
||||||
|
} else { // network sockets
|
||||||
|
st << socket.remote_endpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
r_epn = st.str();
|
||||||
|
if (r_epn.empty()) { // UNIX domain sockets
|
||||||
|
r_epn = "local";
|
||||||
|
}
|
||||||
|
|
||||||
_serverLogger->info("Start client session: remote endpoint <{}> (session thread ID = {})", r_epn, thr_id);
|
_serverLogger->info("Start client session: remote endpoint <{}> (session thread ID = {})", r_epn, thr_id);
|
||||||
|
|
||||||
|
|||||||
14
cxx/mount_server.cpp
Normal file
14
cxx/mount_server.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "comm_server.h"
|
||||||
|
|
||||||
|
#include <spdlog/sinks/basic_file_sink.h>
|
||||||
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
asio::io_context ctx;
|
||||||
|
|
||||||
|
mcc::MccMountServer server(ctx, spdlog::stdout_color_mt("STDOUT_LOGGER"));
|
||||||
|
|
||||||
|
|
||||||
|
ctx.run();
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user