#include "parselink/server.h" #include "parselink/logging.h" #include "parselink/msgpack/core/packer.h" #include "parselink/msgpack/core/unpacker.h" #include "parselink/proto/parser.h" #include "parselink/proto/session.h" #include "parselink/utility/file.h" #include #include #include #include #include #include #include #include #include #include using namespace parselink; using namespace std::chrono_literals; namespace net = boost::asio; using udp = net::ip::udp; namespace { logging::logger logger{"udp.server"}; constexpr auto no_ex_coro = net::as_tuple(net::use_awaitable); } // namespace class udp_server : public server { public: udp_server(std::string_view address, std::uint16_t port) noexcept; std::error_code run() noexcept; private: net::awaitable listen() noexcept; net::io_context io_context_; udp::endpoint local_endpoint_; std::map remotes_; }; udp_server::udp_server(std::string_view address, std::uint16_t port) noexcept : io_context_{1} , local_endpoint_{ net::ip::address::from_string(std::string{address}), port} { // Load keys, config data from file. logger.debug("Creating server."); } net::awaitable udp_server::listen() noexcept { auto exec = co_await net::this_coro::executor; logger.debug("Binding listener socket to {}.", local_endpoint_); udp::socket listener{exec, local_endpoint_}; while (true) { udp::endpoint remote; std::array buff; auto [ec, br] = co_await listener.async_receive_from( net::buffer(buff), remote, no_ex_coro); if (!ec) { logger.debug("From {}: {}", remote, std::span(buff.begin(), br)); } } co_return; } std::error_code udp_server::run() noexcept { co_spawn(io_context_, listen(), net::detached); io_context_.run(); return {}; } std::unique_ptr parselink::make_server( std::string_view address, std::uint16_t user_port, std::uint16_t) { using impl = udp_server; return std::make_unique(address, user_port); }