106 lines
3.6 KiB
C++
106 lines
3.6 KiB
C++
#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 "Settings.h"
|
|
#include "WeChat/Corporation/Context.h"
|
|
#include <boost/asio/strand.hpp>
|
|
|
|
namespace Older {
|
|
|
|
class ApplicationPrivate {
|
|
public:
|
|
std::shared_ptr<boost::urls::router<Application::RequestHandler>> router;
|
|
std::shared_ptr<boost::asio::ip::tcp::acceptor> acceptor;
|
|
};
|
|
|
|
Application::Application() : m_d{new ApplicationPrivate()} {
|
|
using namespace boost::urls;
|
|
using namespace Core;
|
|
m_d->router = std::make_shared<router<RequestHandler>>();
|
|
|
|
m_messageManager = Singleton<MessageManager>::construct();
|
|
m_settings = Singleton<Settings>::construct();
|
|
|
|
m_ioContext = Singleton<IoContext>::construct(m_settings->threads());
|
|
|
|
m_database = Singleton<Database>::construct();
|
|
m_database->open(m_settings->sqlitePath());
|
|
|
|
m_corporationContext = Singleton<WeChat::Corporation::Context>::construct(*m_ioContext->ioContext());
|
|
m_corporationContext->start();
|
|
|
|
m_d->router->insert("/api/v1/notify", [this](HttpSession &session, const Request &request, const matches &matches) {
|
|
auto manager = Singleton<MessageManager>::instance();
|
|
if (manager) {
|
|
manager->publish<NotifyServerChan>(request);
|
|
}
|
|
session.reply(ServiceLogic::make_200<boost::beast::http::string_body>(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<boost::asio::ip::tcp::acceptor>(*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<Settings>::instance();
|
|
ServiceLogic::live2dBackend();
|
|
ServiceLogic::visitAnalysis();
|
|
startAcceptHttpConnections(settings->server(), settings->port());
|
|
m_ioContext->run();
|
|
return 0;
|
|
}
|
|
|
|
void Application::asyncAcceptHttpConnections() {
|
|
auto socket = std::make_shared<boost::asio::ip::tcp::socket>(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<HttpSession>(std::move(*socket), self->m_d->router);
|
|
session->run();
|
|
}
|
|
self->asyncAcceptHttpConnections();
|
|
});
|
|
}
|
|
} // namespace Older
|