diff --git a/test/websocket/stream.cpp b/test/websocket/stream.cpp index 084019eb..53a16bdd 100644 --- a/test/websocket/stream.cpp +++ b/test/websocket/stream.cpp @@ -1416,7 +1416,10 @@ public: yield_to_mf(ep, &stream_test::testAsyncClient); } { - async_echo_server server(true, any, 4); + error_code ec; + async_echo_server server{nullptr, 4}; + server.open(true, any, ec); + BEAST_EXPECTS(! ec, ec.message()); auto const ep = server.local_endpoint(); testSyncClient(ep); testAsyncWriteFrame(ep); diff --git a/test/websocket/websocket_async_echo_server.hpp b/test/websocket/websocket_async_echo_server.hpp index 8954eb55..a270ed45 100644 --- a/test/websocket/websocket_async_echo_server.hpp +++ b/test/websocket/websocket_async_echo_server.hpp @@ -18,6 +18,8 @@ #include #include +#include + namespace beast { namespace websocket { @@ -31,38 +33,21 @@ public: using socket_type = boost::asio::ip::tcp::socket; private: - bool log_ = false; + std::ostream* log_; boost::asio::io_service ios_; socket_type sock_; boost::asio::ip::tcp::acceptor acceptor_; std::vector thread_; + boost::optional work_; public: - async_echo_server(bool server, - endpoint_type const& ep, std::size_t threads) - : sock_(ios_) + async_echo_server(std::ostream* log, + std::size_t threads) + : log_(log) + , sock_(ios_) , acceptor_(ios_) + , work_(ios_) { - if(server) - { - error_code ec; - acceptor_.open(ep.protocol(), ec); - maybe_throw(ec, "open"); - acceptor_.set_option( - boost::asio::socket_base::reuse_address{true}); - acceptor_.bind(ep, ec); - maybe_throw(ec, "bind"); - acceptor_.listen( - boost::asio::socket_base::max_connections, ec); - maybe_throw(ec, "listen"); - acceptor_.async_accept(sock_, - std::bind(&async_echo_server::on_accept, this, - beast::asio::placeholders::error)); - } - else - { - Peer{log_, std::move(sock_), ep}; - } thread_.reserve(threads); for(std::size_t i = 0; i < threads; ++i) thread_.emplace_back( @@ -71,6 +56,7 @@ public: ~async_echo_server() { + work_ = boost::none; error_code ec; ios_.dispatch( [&]{ acceptor_.close(ec); }); @@ -78,6 +64,46 @@ public: t.join(); } + void + open(bool server, + endpoint_type const& ep, error_code& ec) + { + if(server) + { + acceptor_.open(ep.protocol(), ec); + if(ec) + { + if(log_) + (*log_) << "open: " << ec.message() << std::endl; + return; + } + acceptor_.set_option( + boost::asio::socket_base::reuse_address{true}); + acceptor_.bind(ep, ec); + if(ec) + { + if(log_) + (*log_) << "bind: " << ec.message() << std::endl; + return; + } + acceptor_.listen( + boost::asio::socket_base::max_connections, ec); + if(ec) + { + if(log_) + (*log_) << "listen: " << ec.message() << std::endl; + return; + } + acceptor_.async_accept(sock_, + std::bind(&async_echo_server::on_accept, this, + beast::asio::placeholders::error)); + } + else + { + Peer{*this, std::move(sock_), ep}; + } + } + endpoint_type local_endpoint() const { @@ -89,7 +115,7 @@ private: { struct data { - bool log; + async_echo_server& server; int state = 0; boost::optional ep; stream ws; @@ -98,8 +124,9 @@ private: beast::streambuf db; int id; - data(bool log_, socket_type&& sock_) - : log(log_) + data(async_echo_server& server_, + socket_type&& sock_) + : server(server_) , ws(std::move(sock_)) , strand(ws.get_io_service()) , id([] @@ -110,9 +137,9 @@ private: { } - data(bool log_, socket_type&& sock_, - endpoint_type const& ep_) - : log(log_) + data(async_echo_server& server_, + socket_type&& sock_, endpoint_type const& ep_) + : server(server_) , ep(ep_) , ws(std::move(sock_)) , strand(ws.get_io_service()) @@ -152,15 +179,16 @@ private: template explicit - Peer(bool log, socket_type&& sock, Args&&... args) - : d_(std::make_shared(log, + Peer(async_echo_server& server, + socket_type&& sock, Args&&... args) + : d_(std::make_shared(server, std::forward(sock), std::forward(args)...)) { auto& d = *d_; d.ws.set_option(decorate(identity{})); d.ws.set_option(read_message_max(64 * 1024 * 1024)); - //d.ws.set_option(auto_fragment{false}); + d.ws.set_option(auto_fragment{false}); //d.ws.set_option(write_buffer_size{64 * 1024}); run(); } @@ -291,10 +319,10 @@ private: fail(error_code ec, std::string what) { auto& d = *d_; - if(d.log) + if(d.server.log_) { if(ec != error::closed) - std::cerr << "#" << d_->id << " " << + (*d.server.log_) << "#" << d.id << " " << what << ": " << ec.message() << std::endl; } } @@ -304,7 +332,7 @@ private: fail(error_code ec, std::string what) { if(log_) - std::cerr << what << ": " << + (*log_) << what << ": " << ec.message() << std::endl; } @@ -330,7 +358,7 @@ private: acceptor_.async_accept(sock_, std::bind(&async_echo_server::on_accept, this, beast::asio::placeholders::error)); - Peer{false, std::move(sock)}; + Peer{*this, std::move(sock)}; } }; diff --git a/test/websocket/websocket_echo.cpp b/test/websocket/websocket_echo.cpp index 636087b4..a4ddee49 100644 --- a/test/websocket/websocket_echo.cpp +++ b/test/websocket/websocket_echo.cpp @@ -8,17 +8,27 @@ #include "websocket_async_echo_server.hpp" #include "websocket_sync_echo_server.hpp" #include +#include int main() { using endpoint_type = boost::asio::ip::tcp::endpoint; using address_type = boost::asio::ip::address; - beast::websocket::async_echo_server s1(true, endpoint_type{ - address_type::from_string("127.0.0.1"), 6000 }, 4); + try + { + boost::system::error_code ec; + beast::websocket::async_echo_server s1{nullptr, 1}; + s1.open(true, endpoint_type{ + address_type::from_string("127.0.0.1"), 6000 }, ec); - beast::websocket::sync_echo_server s2(true, endpoint_type{ - address_type::from_string("127.0.0.1"), 6001 }); + beast::websocket::sync_echo_server s2(true, endpoint_type{ + address_type::from_string("127.0.0.1"), 6001 }); - beast::test::sig_wait(); + beast::test::sig_wait(); + } + catch(std::exception const& e) + { + std::cout << "Error: " << e.what() << std::endl; + } }