#include "Application.h" #include "Core/IoContext.h" #include "Core/Logger.h" #include "Core/Singleton.h" #include "HttpSession.h" #include "Router/router.hpp" #include "ServiceLogic.h" #include "Settings.h" #include "WebRTC/SignalServer.h" #include #include namespace Danki { class ApplicationPrivate { public: std::shared_ptr> router; std::shared_ptr acceptor; }; Application::Application() : m_d{new ApplicationPrivate()} { using namespace boost::urls; using namespace Core; m_settings = Singleton::construct(); m_ioContext = Singleton::construct(m_settings->threads()); m_d->router = std::make_shared>(); m_signalServer = std::make_shared(*this); } void Application::insertUrl(std::string_view url, RequestHandler &&handler) { m_d->router->insert(url, std::move(handler)); } boost::asio::io_context &Application::ioContext() { return *m_ioContext->ioContext(); } int Application::exec() { using namespace Core; auto settings = Singleton::instance(); ServiceLogic::staticFilesDeploy(); startAcceptHttpConnections(settings->server(), settings->port()); m_ioContext->run(); return 0; } void Application::startAcceptHttpConnections(const std::string &address, uint16_t port) { m_d->acceptor = std::make_shared(*m_ioContext->ioContext()); boost::beast::error_code error; boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::make_address(address), port); m_d->acceptor->open(endpoint.protocol(), error); if (error) { LOG(error) << error.message(); return; } m_d->acceptor->set_option(boost::asio::socket_base::reuse_address(true), error); if (error) { LOG(error) << error.message(); return; } m_d->acceptor->bind(endpoint, error); if (error) { LOG(error) << error.message(); return; } m_d->acceptor->listen(boost::asio::socket_base::max_listen_connections, error); if (error) { LOG(error) << error.message(); return; } asyncAcceptHttpConnections(); } void Application::asyncAcceptHttpConnections() { auto socket = std::make_shared(boost::asio::make_strand(*m_ioContext->ioContext())); m_d->acceptor->async_accept(*socket, [self{shared_from_this()}, socket](const boost::system::error_code &error) { if (error) { if (error == boost::asio::error::operation_aborted) return; LOG(error) << error.message(); } else { auto session = std::make_shared(std::move(*socket), self->m_d->router); session->run(); } self->asyncAcceptHttpConnections(); }); } } // namespace Danki