Anonymous
Boost Beast (Asio) httpserver и httpclient: рекомендации по использованию io_context
Сообщение
Anonymous » 12 июн 2025, 11:08
Недавно я реализовал асинхронный HTTP -сервер и клиент на основе C ++ Boost Beast (V.1.83). Я новичок в подходе io_context, и даже если все это работает нормально, я совсем не убежден в реализации. Посмотреть здесь для некоторых предложений по лучшим практикам по этому вопросу.
относительно httpserver
strong>http_server.hpp
Код: Выделить всё
namespace http = boost::beast::http;
namespace net = boost::asio;
namespace beast = boost::beast;
namespace bsys = boost::system;
using tcp = net::ip::tcp;
class HttpServer
{
public:
HttpServer(net::io_context& ctx_, Router& router, asio::ip::address host_address, unsigned short tcp_port, int thread_num = 1);
private:
tcp::acceptor acceptor_;
next::webapi::Router router_;
void AcceptConnection();
void HandleRequest(std::shared_ptr socket);
};
< /code>
Уведомление io_context < /em> здесь передается в качестве ссылки, как это предлагается повсюду.
[b]http_server.cpp[/b]
>>>#include "next_webapi/http_server.hpp"
using namespace next::webapi;
HttpServer::HttpServer(net::io_context& ctx_, Router &router, asio::ip::address host_address, unsigned short tcp_port, int thread_num)
: acceptor_(ctx_, boost::asio::ip::tcp::endpoint(host_address, tcp_port))
{
AcceptConnection();
}
void HttpServer::HandleRequest(std::shared_ptr socket)
{
auto dyn_buffer = std::make_shared();
auto request = std::make_shared();
request->body_limit(std::numeric_limits::max());
http::async_read(*socket, *dyn_buffer, *request,
[this, socket, dyn_buffer, request](bsys::error_code ec, std::size_t)
{
if (!ec)
{
router_.RouteRequest(std::move(*socket), request->release());
}
});
}
void HttpServer::AcceptConnection()
{
acceptor_.async_accept(
[this](bsys::error_code ec, tcp::socket socket)
{
if (!ec)
{
auto new_socket = std::make_shared(std::move(socket));
HandleRequest(new_socket);
}
AcceptConnection();
});
}
main.cpp
int main(int argc, char *argv[])
{
// Initialize stuff here...
// HTTP Server init
next::webapi::HttpServer http_server(http_srv_ctx, router, boost::beast::net::ip::make_address(rest_local_endpoint_address), rest_local_endpoint_port);
std::thread t([&http_srv_ctx]()
{ http_srv_ctx.run(); });
// More stuff to initialize and do...
return 0;
}
< /code>
Здесь все реализовано в значительной степени, как видно во всех примерах вокруг. Он работает, но: < /p>
Разве невозможно было бы иметь IO_Context в качестве переменной -члена httpserver, и в какой точке run () < /em> следует называться? Я положил io_context.run () в отдельный поток (также это некоторые из примера). Это действительно правильный подход?#include
#include
#include
namespace http = boost::beast::http;
namespace net = boost::asio;
namespace beast = boost::beast;
namespace bsys = boost::system;
using tcp = net::ip::tcp;
class HttpClient
{
public:
HttpClient(std::string dst_host, unsigned short dst_port);
~HttpClient(){};
/**
* Generic request with all parameters settable
*/
void Request(http::verb verb, std::string target_path,
const std::function &,
std::map params = {{}},
std::string body = "",
std::string content_type = "application/json");
private:
net::io_context ctx_;
beast::tcp_stream socket_stream_;
tcp::resolver resolver_;
beast::flat_buffer buffer_;
std::string dst_host_;
unsigned short dst_port_;
http::request request_;
http::response response_;
std::function callback_;
unsigned short timeout_connect_s_ = 1;
unsigned short timeout_write_s_ = 1;
};
< /code>
Здесь я попробовал io_context как переменную члена, поэтому ссылка не передается в Httpclient извне.
shrong>http_client.cpp
>#include "next_webapi/http_client.hpp"
HttpClient::HttpClient(std::string dst_host, unsigned short dst_port)
: resolver_(ctx_),
socket_stream_(ctx_),
dst_host_(dst_host),
dst_port_(dst_port)
{}
void HttpClient::Request(http::verb verb, std::string target_path,
const std::function &callback,
std::map params,
std::string body,
std::string content_type)
{
callback_ = callback;
request_ = {};
response_ = {};
// Build query string from parameters
std::stringstream param_query_ss;
param_query_ss
Мне не нравится подход клиента. Как это можно было сделать лучше? Как это можно было сделать лучше?
Подробнее здесь:
https://stackoverflow.com/questions/796 ... ntext-usag
1749715684
Anonymous
Недавно я реализовал асинхронный HTTP -сервер и клиент на основе C ++ Boost Beast (V.1.83). Я новичок в подходе io_context, и даже если все это работает нормально, я совсем не убежден в реализации. Посмотреть здесь для некоторых предложений по лучшим практикам по этому вопросу. относительно httpserver strong>http_server.hpp [code]namespace http = boost::beast::http; namespace net = boost::asio; namespace beast = boost::beast; namespace bsys = boost::system; using tcp = net::ip::tcp; class HttpServer { public: HttpServer(net::io_context& ctx_, Router& router, asio::ip::address host_address, unsigned short tcp_port, int thread_num = 1); private: tcp::acceptor acceptor_; next::webapi::Router router_; void AcceptConnection(); void HandleRequest(std::shared_ptr socket); }; < /code> Уведомление io_context < /em> здесь передается в качестве ссылки, как это предлагается повсюду. [b]http_server.cpp[/b] >>>#include "next_webapi/http_server.hpp" using namespace next::webapi; HttpServer::HttpServer(net::io_context& ctx_, Router &router, asio::ip::address host_address, unsigned short tcp_port, int thread_num) : acceptor_(ctx_, boost::asio::ip::tcp::endpoint(host_address, tcp_port)) { AcceptConnection(); } void HttpServer::HandleRequest(std::shared_ptr socket) { auto dyn_buffer = std::make_shared(); auto request = std::make_shared(); request->body_limit(std::numeric_limits::max()); http::async_read(*socket, *dyn_buffer, *request, [this, socket, dyn_buffer, request](bsys::error_code ec, std::size_t) { if (!ec) { router_.RouteRequest(std::move(*socket), request->release()); } }); } void HttpServer::AcceptConnection() { acceptor_.async_accept( [this](bsys::error_code ec, tcp::socket socket) { if (!ec) { auto new_socket = std::make_shared(std::move(socket)); HandleRequest(new_socket); } AcceptConnection(); }); } [/code] [b] main.cpp[/b] int main(int argc, char *argv[]) { // Initialize stuff here... // HTTP Server init next::webapi::HttpServer http_server(http_srv_ctx, router, boost::beast::net::ip::make_address(rest_local_endpoint_address), rest_local_endpoint_port); std::thread t([&http_srv_ctx]() { http_srv_ctx.run(); }); // More stuff to initialize and do... return 0; } < /code> Здесь все реализовано в значительной степени, как видно во всех примерах вокруг. Он работает, но: < /p> [list] [*] Разве невозможно было бы иметь IO_Context в качестве переменной -члена httpserver, и в какой точке run () < /em> следует называться? Я положил io_context.run () в отдельный поток (также это некоторые из примера). Это действительно правильный подход?#include #include #include namespace http = boost::beast::http; namespace net = boost::asio; namespace beast = boost::beast; namespace bsys = boost::system; using tcp = net::ip::tcp; class HttpClient { public: HttpClient(std::string dst_host, unsigned short dst_port); ~HttpClient(){}; /** * Generic request with all parameters settable */ void Request(http::verb verb, std::string target_path, const std::function &, std::map params = {{}}, std::string body = "", std::string content_type = "application/json"); private: net::io_context ctx_; beast::tcp_stream socket_stream_; tcp::resolver resolver_; beast::flat_buffer buffer_; std::string dst_host_; unsigned short dst_port_; http::request request_; http::response response_; std::function callback_; unsigned short timeout_connect_s_ = 1; unsigned short timeout_write_s_ = 1; }; < /code> Здесь я попробовал io_context как переменную члена, поэтому ссылка не передается в Httpclient извне. shrong>http_client.cpp >#include "next_webapi/http_client.hpp" HttpClient::HttpClient(std::string dst_host, unsigned short dst_port) : resolver_(ctx_), socket_stream_(ctx_), dst_host_(dst_host), dst_port_(dst_port) {} void HttpClient::Request(http::verb verb, std::string target_path, const std::function &callback, std::map params, std::string body, std::string content_type) { callback_ = callback; request_ = {}; response_ = {}; // Build query string from parameters std::stringstream param_query_ss; param_query_ss Мне не нравится подход клиента. Как это можно было сделать лучше? Как это можно было сделать лучше? [/list] Подробнее здесь: [url]https://stackoverflow.com/questions/79663141/boost-beast-asio-httpserver-and-httpclient-recommendations-on-io-context-usag[/url]