diff --git a/main.cpp b/main.cpp index 7849cd3..aae055b 100644 --- a/main.cpp +++ b/main.cpp @@ -15,6 +15,7 @@ using namespace std::literals; namespace sys = boost::system; namespace http = boost::beast::http; using namespace std; +using net::ip::tcp; // Запрос, тело которого представлено в виде строки using StringRequest = http::request; @@ -70,6 +71,7 @@ int main() const unsigned num_threads = std::thread::hardware_concurrency(); net::io_context ioc(num_threads); + tcp::acceptor acceptor(net::make_strand(ioc)); // Подписываемся на сигналы и при их получении завершаем работу сервера net::signal_set signals(ioc, SIGINT, SIGTERM); diff --git a/src/listener.h b/src/listener.h index b072c40..3e10a0a 100644 --- a/src/listener.h +++ b/src/listener.h @@ -8,9 +8,12 @@ #include #include +#include "session.h" + namespace http_server { namespace net = boost::asio; +namespace sys = boost::system; using tcp = net::ip::tcp; namespace beast = boost::beast; namespace http = beast::http; @@ -28,13 +31,41 @@ class Listener : public std::enable_shared_from_this> const tcp::endpoint& endpoint, Handler&& request_handler) : ioc_(ioc), - acceptor_(net::make_strand(ioc)), - request_handler_(std::forward(request_handler)) + acceptor_(net::make_strand(ioc)), + request_handler_(std::forward(request_handler)) + { + acceptor_.open(endpoint.protocol()); + acceptor_.set_option(net::socket_base::reuse_address(true)); + acceptor_.bind(endpoint); + acceptor_.listen(net::socket_base::max_listen_connections); + } + + void Run() + { + DoAccept(); + } + + private: + void DoAccept() + { + acceptor_.async_accept(net::make_strand(ioc_), + beast::bind_front_handler(&Listener::DoAccept, + this->shared_from_this())); + } + + void OnAccept(sys::error_code ec, tcp::socket socket) + { + if (ec) { - acceptor_.open(endpoint.protocol()); - acceptor_.set_option(net::socket_base::reuse_address(true)); - acceptor_.bind(endpoint); - acceptor_.listen(net::socket_base::max_listen_connections); + return ReportError(ec, "accept"sv); } + + AsyncRunSession(std::move(socket)); + + DoAccept(); + } + + void AsyncRunSession(tcp::socket&& socket) + {} }; } // namespace http_server \ No newline at end of file diff --git a/src/session_base.cpp b/src/session_base.cpp index 73a9ed7..9b6c3b6 100644 --- a/src/session_base.cpp +++ b/src/session_base.cpp @@ -1,8 +1,12 @@ #include "http_server.h" +#include "session_base.h" #include #include namespace http_server { +void ReportError(beast::error_code ec, std::string_view what) { + std::cerr << what << ": "sv << ec.message() << std::endl; +} } // namespace http_server diff --git a/src/session_base.h b/src/session_base.h index 300685c..0cc78cf 100644 --- a/src/session_base.h +++ b/src/session_base.h @@ -3,6 +3,9 @@ // boost.beast будет использовать std::string_view вместо boost::string_view #define BOOST_BEAST_USE_STD_STRING_VIEW +#include +#include + #include #include #include @@ -14,6 +17,11 @@ namespace net = boost::asio; using tcp = net::ip::tcp; namespace beast = boost::beast; namespace http = beast::http; + +using namespace std::literals; + +void ReportError(beast::error_code ec, std::string_view what); + class SessionBase { // Напишите недостающий код, используя информацию из урока };