Запущенный асинхронный сервер
This commit is contained in:
parent
a80508d3a8
commit
0ff54f68f2
2
main.cpp
2
main.cpp
@ -88,7 +88,7 @@ int main()
|
|||||||
constexpr net::ip::port_type port = 8080;
|
constexpr net::ip::port_type port = 8080;
|
||||||
http_server::ServeHttp(ioc, {address, port}, [](auto&& req, auto&& sender)
|
http_server::ServeHttp(ioc, {address, port}, [](auto&& req, auto&& sender)
|
||||||
{
|
{
|
||||||
// sender(HandleRequest(std::forward<decltype(req)>(req)));
|
sender(HandleRequest(std::forward<decltype(req)>(req)));
|
||||||
});
|
});
|
||||||
|
|
||||||
net::steady_timer t {ioc, 30s};
|
net::steady_timer t {ioc, 30s};
|
||||||
|
@ -16,6 +16,8 @@ namespace http_server
|
|||||||
template<typename RequestHandler>
|
template<typename RequestHandler>
|
||||||
void ServeHttp(net::io_context& ioc, const tcp::endpoint& endpoint, RequestHandler&& handler)
|
void ServeHttp(net::io_context& ioc, const tcp::endpoint& endpoint, RequestHandler&& handler)
|
||||||
{
|
{
|
||||||
// Напишите недостающий код, используя информацию из урока
|
using MyListener = Listener<std::decay_t<RequestHandler>>;
|
||||||
|
|
||||||
|
std::make_shared<MyListener>(ioc, endpoint, std::forward<RequestHandler>(handler))->Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,13 @@ class Session : public SessionBase, public std::enable_shared_from_this<Session<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void HandleRequest(HttpRequest&& request) override {}
|
void HandleRequest(HttpRequest&& request) override {
|
||||||
|
// Захватываем умный указатель на текущий объект Session в лямбде,
|
||||||
|
// чтобы продлить время жизни сессии до вызова лямбды.
|
||||||
|
// Используется generic-лямбда функция, способная принять response произвольного типа
|
||||||
|
request_handler_(std::move(request), [self = this->shared_from_this()](auto&& response) {
|
||||||
|
self->Write(std::move(response));
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace http_server
|
} // namespace http_server
|
@ -6,11 +6,12 @@
|
|||||||
|
|
||||||
namespace http_server
|
namespace http_server
|
||||||
{
|
{
|
||||||
void ReportError(beast::error_code ec, std::string_view what) {
|
void ReportError(beast::error_code ec, std::string_view what)
|
||||||
|
{
|
||||||
std::cerr << what << ": "sv << ec.message() << std::endl;
|
std::cerr << what << ": "sv << ec.message() << std::endl;
|
||||||
}
|
}
|
||||||
SessionBase::SessionBase(tcp::socket&& socket)
|
SessionBase::SessionBase(tcp::socket&& socket)
|
||||||
: stream_(std::move(socket))
|
: stream_(std::move(socket))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -49,4 +50,21 @@ void SessionBase::Close()
|
|||||||
stream_.socket().shutdown(tcp::socket::shutdown_send, ec);
|
stream_.socket().shutdown(tcp::socket::shutdown_send, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SessionBase::OnWrite(bool close,
|
||||||
|
boost::beast::error_code ec,
|
||||||
|
std::size_t bytes_written)
|
||||||
|
{
|
||||||
|
if (ec) {
|
||||||
|
return ReportError(ec, "write"sv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close) {
|
||||||
|
// Семантика ответа требует закрыть соединение
|
||||||
|
return Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Считываем следующий запрос
|
||||||
|
Read();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace http_server
|
} // namespace http_server
|
||||||
|
@ -40,6 +40,18 @@ class SessionBase {
|
|||||||
protected:
|
protected:
|
||||||
explicit SessionBase(tcp::socket&& socket);
|
explicit SessionBase(tcp::socket&& socket);
|
||||||
|
|
||||||
|
template <typename Body, typename Fields>
|
||||||
|
void Write(http::response<Body, Fields>&& response) {
|
||||||
|
// Запись выполняется асинхронно, поэтому response перемещаем в область кучи
|
||||||
|
auto safe_response = std::make_shared<http::response<Body, Fields>>(std::move(response));
|
||||||
|
|
||||||
|
auto self = GetSharedThis();
|
||||||
|
http::async_write(stream_, *safe_response,
|
||||||
|
[safe_response, self](beast::error_code ec, std::size_t bytes_written) {
|
||||||
|
self->OnWrite(safe_response->need_eof(), ec, bytes_written);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
beast::tcp_stream stream_;
|
beast::tcp_stream stream_;
|
||||||
beast::flat_buffer buffer_;
|
beast::flat_buffer buffer_;
|
||||||
@ -50,5 +62,7 @@ class SessionBase {
|
|||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
virtual void HandleRequest(HttpRequest&& request) = 0;
|
virtual void HandleRequest(HttpRequest&& request) = 0;
|
||||||
|
|
||||||
|
void OnWrite(bool close, beast::error_code ec, [[maybe_unused]] std::size_t bytes_written);
|
||||||
};
|
};
|
||||||
} // namespace http_server
|
} // namespace http_server
|
Loading…
x
Reference in New Issue
Block a user