#include "Application.h" #include "Base/Messages.h" #include "Core/IoContext.h" #include "Core/MessageManager.h" #include "Core/Singleton.h" #include "Database.h" #include "HttpSession.h" #include "Router/router.hpp" #include "ServiceLogic.h" #include "SessionStore.h" #include "Settings.h" #include "WeChat/Corporation/Context.h" #include "WebRTC/SignalServer.h" #include namespace Older { 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_d->router = std::make_shared>(); m_messageManager = Singleton::construct(); m_settings = Singleton::construct(); m_ioContext = Singleton::construct(m_settings->threads()); m_database = Singleton::construct(); m_database->open(m_settings->sqlitePath()); m_sessionStore = Singleton::construct(*m_ioContext->ioContext()); m_corporationContext = Singleton::construct(*m_ioContext->ioContext()); m_corporationContext->start(); m_signalServer = std::make_shared(*this); m_d->router->insert("/api/v1/notify", [this](HttpSession &session, const Request &request, const matches &matches) { auto manager = Singleton::instance(); if (manager) { manager->publish(request); } session.reply(ServiceLogic::make_200(request, "notify successed.\n", "text/html")); }); } boost::asio::io_context &Application::ioContext() { return *m_ioContext->ioContext(); } 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::insertUrl(std::string_view url, RequestHandler &&handler) { m_d->router->insert(url, std::move(handler)); } int Application::exec() { using namespace Core; auto settings = Singleton::instance(); ServiceLogic::live2dBackend(); ServiceLogic::visitAnalysis(); ServiceLogic::userAccount(); ServiceLogic::staticFilesDeploy(); startAcceptHttpConnections(settings->server(), settings->port()); m_ioContext->run(); return 0; } 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 Older