2023-09-13 14:20:40 +02:00
|
|
|
|
#include "src/sdk.h"
|
|
|
|
|
//
|
|
|
|
|
#include <boost/asio/signal_set.hpp>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <mutex>
|
|
|
|
|
#include <thread>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include "src/http_server.h"
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
namespace net = boost::asio;
|
|
|
|
|
using namespace std::literals;
|
|
|
|
|
namespace sys = boost::system;
|
|
|
|
|
namespace http = boost::beast::http;
|
2023-09-13 14:57:22 +02:00
|
|
|
|
using namespace std;
|
2023-09-13 16:01:44 +02:00
|
|
|
|
using net::ip::tcp;
|
2023-09-13 14:20:40 +02:00
|
|
|
|
|
|
|
|
|
// Запрос, тело которого представлено в виде строки
|
|
|
|
|
using StringRequest = http::request<http::string_body>;
|
|
|
|
|
// Ответ, тело которого представлено в виде строки
|
|
|
|
|
using StringResponse = http::response<http::string_body>;
|
|
|
|
|
|
2024-01-20 10:24:00 +01:00
|
|
|
|
struct content_type
|
2023-09-13 14:20:40 +02:00
|
|
|
|
{
|
2024-01-20 10:24:00 +01:00
|
|
|
|
content_type() = delete;
|
|
|
|
|
constexpr static std::string_view k_TextHTML = "text/html"sv;
|
|
|
|
|
// При необходимости внутрь content_type можно добавить и другие типы контента
|
2023-09-13 14:20:40 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Создаёт StringResponse с заданными параметрами
|
2023-11-04 00:05:40 +01:00
|
|
|
|
StringResponse MakeStringResponse(http::status status,
|
|
|
|
|
std::string_view body,
|
|
|
|
|
unsigned http_version,
|
2023-09-13 14:20:40 +02:00
|
|
|
|
bool keep_alive,
|
2024-01-20 10:24:00 +01:00
|
|
|
|
std::string_view content_type = content_type::k_TextHTML)
|
2023-09-13 14:20:40 +02:00
|
|
|
|
{
|
|
|
|
|
StringResponse response(status, http_version);
|
|
|
|
|
response.set(http::field::content_type, content_type);
|
|
|
|
|
response.body() = body;
|
|
|
|
|
response.content_length(body.size());
|
|
|
|
|
response.keep_alive(keep_alive);
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StringResponse HandleRequest(StringRequest&& req)
|
|
|
|
|
{
|
2024-01-20 10:46:22 +01:00
|
|
|
|
auto route = req.target();
|
|
|
|
|
|
2023-11-04 00:05:40 +01:00
|
|
|
|
return MakeStringResponse(http::status::ok,
|
2024-01-20 10:24:00 +01:00
|
|
|
|
"Hello, World!"sv,
|
2023-11-04 00:05:40 +01:00
|
|
|
|
req.version(),
|
|
|
|
|
req.keep_alive());
|
2023-09-13 14:20:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Запускает функцию fn на n потоках, включая текущий
|
|
|
|
|
template<typename Fn>
|
|
|
|
|
void RunWorkers(unsigned n, const Fn& fn)
|
|
|
|
|
{
|
|
|
|
|
n = std::max(1u, n);
|
|
|
|
|
std::vector<std::jthread> workers;
|
|
|
|
|
workers.reserve(n - 1);
|
|
|
|
|
// Запускаем n-1 рабочих потоков, выполняющих функцию fn
|
|
|
|
|
while (--n)
|
|
|
|
|
{
|
|
|
|
|
workers.emplace_back(fn);
|
|
|
|
|
}
|
|
|
|
|
fn();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
{
|
|
|
|
|
const unsigned num_threads = std::thread::hardware_concurrency();
|
|
|
|
|
|
|
|
|
|
net::io_context ioc(num_threads);
|
2024-02-21 03:57:28 +01:00
|
|
|
|
tcp::acceptor acceptor(net::make_strand(ioc));
|
2023-09-13 14:20:40 +02:00
|
|
|
|
|
|
|
|
|
// Подписываемся на сигналы и при их получении завершаем работу сервера
|
|
|
|
|
net::signal_set signals(ioc, SIGINT, SIGTERM);
|
2023-11-04 00:05:40 +01:00
|
|
|
|
signals.async_wait([&ioc](const sys::error_code& ec,
|
|
|
|
|
[[maybe_unused]] int signal_number)
|
2023-09-13 14:20:40 +02:00
|
|
|
|
{
|
|
|
|
|
if (!ec)
|
|
|
|
|
{
|
2023-11-04 00:05:40 +01:00
|
|
|
|
cout << "Signal "sv << signal_number << " received"sv
|
|
|
|
|
<< endl;
|
2023-09-13 14:20:40 +02:00
|
|
|
|
ioc.stop();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2024-02-21 03:57:28 +01:00
|
|
|
|
const auto address = net::ip::make_address("0.0.0.0");
|
|
|
|
|
constexpr net::ip::port_type port = 8080;
|
2023-09-13 14:20:40 +02:00
|
|
|
|
http_server::ServeHttp(ioc, {address, port}, [](auto&& req, auto&& sender)
|
|
|
|
|
{
|
2023-09-14 20:39:36 +02:00
|
|
|
|
sender(HandleRequest(std::forward<decltype(req)>(req)));
|
2023-09-13 14:20:40 +02:00
|
|
|
|
});
|
|
|
|
|
|
2023-09-13 14:57:22 +02:00
|
|
|
|
net::steady_timer t {ioc, 30s};
|
|
|
|
|
|
|
|
|
|
t.async_wait([](sys::error_code ec)
|
|
|
|
|
{
|
|
|
|
|
cout << "Timer expired"sv << endl;
|
|
|
|
|
});
|
|
|
|
|
|
2023-09-13 14:20:40 +02:00
|
|
|
|
std::cout << "Server has started..."sv << std::endl;
|
|
|
|
|
|
|
|
|
|
RunWorkers(num_threads, [&ioc]
|
|
|
|
|
{
|
|
|
|
|
ioc.run();
|
|
|
|
|
});
|
|
|
|
|
}
|