From 7028579170d83cb81a97478b620f3cb15a2fd693 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Tue, 17 Jan 2017 14:50:38 -0500 Subject: [PATCH] Squashed 'src/beast/' changes from 1ab7a2f..c00cd37 c00cd37 Set version to 1.0.0-b23 f662e36 Travis CI improvements: b05fa33 Fix message constructor and special members b4722cc Add copy special members 420d1c7 Better logging in async echo server 149e3a2 Add file and line number to thrown exceptions 3e88b83 Tune websocket echo server for performance git-subtree-dir: src/beast git-subtree-split: c00cd37b8a441a92755658014fdde97d515ec7ed --- .travis.yml | 7 +- CHANGELOG.md | 11 ++ include/beast/core/detail/buffer_cat.hpp | 9 +- include/beast/core/detail/type_traits.hpp | 14 +++ include/beast/core/impl/basic_streambuf.ipp | 4 +- include/beast/core/impl/buffers_adapter.ipp | 5 +- include/beast/core/impl/static_streambuf.ipp | 4 +- include/beast/core/static_string.hpp | 22 ++-- include/beast/http/impl/message.ipp | 18 +-- include/beast/http/message.hpp | 19 +++- include/beast/version.hpp | 2 +- include/beast/websocket/impl/stream.ipp | 1 + include/beast/websocket/option.hpp | 10 +- include/beast/zlib/detail/deflate_stream.hpp | 12 +- include/beast/zlib/detail/inflate_stream.hpp | 11 +- scripts/build-and-test.sh | 13 ++- test/http/message.cpp | 14 +++ test/websocket/stream.cpp | 5 +- .../websocket/websocket_async_echo_server.hpp | 105 ++++++++++++------ test/websocket/websocket_echo.cpp | 20 +++- 20 files changed, 221 insertions(+), 85 deletions(-) diff --git a/.travis.yml b/.travis.yml index 96efe8e733..0035abc4c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +sudo: false language: cpp env: @@ -11,7 +12,7 @@ env: - LCOV_ROOT=$HOME/lcov - VALGRIND_ROOT=$HOME/valgrind-install - BOOST_ROOT=$HOME/boost_1_61_0 - - BOOST_URL='http://downloads.sourceforge.net/project/boost/boost/1.61.0/boost_1_61_0.tar.gz?use_mirror=netix' + - BOOST_URL='http://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.tar.gz' packages: &gcc5_pkgs - gcc-5 - g++-5 @@ -30,7 +31,7 @@ packages: &gcc5_pkgs matrix: include: - # GCC/Coverage/Autobahn + # GCC/Coverage/Autobahn (if master or develop branch) - compiler: gcc env: - GCC_VER=5 @@ -77,7 +78,7 @@ before_install: - scripts/install-dependencies.sh script: - - scripts/build-and-test.sh + - travis_retry scripts/build-and-test.sh after_script: - cat nohup.out || echo "nohup.out already deleted" diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac23dea16..515988fbca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +1.0.0-b23 + +* Tune websocket echo server for performance +* Add file and line number to thrown exceptions +* Better logging in async echo server +* Add copy special members +* Fix message constructor and special members +* Travis CI improvements + +-------------------------------------------------------------------------------- + 1.0.0-b22 * Fix broken Intellisense diff --git a/include/beast/core/detail/buffer_cat.hpp b/include/beast/core/detail/buffer_cat.hpp index fdf2b6104f..b94d996566 100644 --- a/include/beast/core/detail/buffer_cat.hpp +++ b/include/beast/core/detail/buffer_cat.hpp @@ -253,7 +253,8 @@ private: reference dereference(C const&) const { - throw std::logic_error("invalid iterator"); + throw detail::make_exception( + "invalid iterator", __FILE__, __LINE__); } template @@ -269,7 +270,8 @@ private: void increment(C const&) { - throw std::logic_error("invalid iterator"); + throw detail::make_exception( + "invalid iterator", __FILE__, __LINE__); } template @@ -310,7 +312,8 @@ private: --iter(); return; } - throw std::logic_error("invalid iterator"); + throw detail::make_exception( + "invalid iterator", __FILE__, __LINE__); } template diff --git a/include/beast/core/detail/type_traits.hpp b/include/beast/core/detail/type_traits.hpp index 24928abddf..f50b3a3c03 100644 --- a/include/beast/core/detail/type_traits.hpp +++ b/include/beast/core/detail/type_traits.hpp @@ -10,6 +10,8 @@ #include #include +#include +#include namespace beast { namespace detail { @@ -78,6 +80,18 @@ struct repeat_tuple<0, T> using type = std::tuple<>; }; +template +Exception +make_exception(char const* reason, char const* file, int line) +{ + char const* n = file; + for(auto p = file; *p; ++p) + if(*p == '\\' || *p == '/') + n = p + 1; + return Exception{std::string(reason) + " (" + + n + ":" + std::to_string(line) + ")"}; +} + } // detail } // beast diff --git a/include/beast/core/impl/basic_streambuf.ipp b/include/beast/core/impl/basic_streambuf.ipp index c70d646bb6..a3fdcef706 100644 --- a/include/beast/core/impl/basic_streambuf.ipp +++ b/include/beast/core/impl/basic_streambuf.ipp @@ -524,8 +524,8 @@ basic_streambuf::basic_streambuf( , alloc_size_(alloc_size) { if(alloc_size <= 0) - throw std::invalid_argument( - "basic_streambuf: invalid alloc_size"); + throw detail::make_exception( + "invalid alloc_size", __FILE__, __LINE__); } template diff --git a/include/beast/core/impl/buffers_adapter.ipp b/include/beast/core/impl/buffers_adapter.ipp index cf537d6e47..309830f1e3 100644 --- a/include/beast/core/impl/buffers_adapter.ipp +++ b/include/beast/core/impl/buffers_adapter.ipp @@ -8,6 +8,7 @@ #ifndef BEAST_IMPL_BUFFERS_ADAPTER_IPP #define BEAST_IMPL_BUFFERS_ADAPTER_IPP +#include #include #include #include @@ -413,8 +414,8 @@ buffers_adapter::prepare(std::size_t n) -> } } if(n > 0) - throw std::length_error( - "no space in buffers_adapter"); + throw detail::make_exception( + "no space", __FILE__, __LINE__); return mutable_buffers_type{*this}; } diff --git a/include/beast/core/impl/static_streambuf.ipp b/include/beast/core/impl/static_streambuf.ipp index 3f19cd7e10..44c4e26107 100644 --- a/include/beast/core/impl/static_streambuf.ipp +++ b/include/beast/core/impl/static_streambuf.ipp @@ -8,6 +8,7 @@ #ifndef BEAST_IMPL_STATIC_STREAMBUF_IPP #define BEAST_IMPL_STATIC_STREAMBUF_IPP +#include #include #include #include @@ -295,7 +296,8 @@ static_streambuf::prepare(std::size_t n) -> mutable_buffers_type { if(n > static_cast(end_ - out_)) - throw std::length_error("no space in streambuf"); + throw detail::make_exception( + "no space in streambuf", __FILE__, __LINE__); last_ = out_ + n; return mutable_buffers_type{out_, n}; } diff --git a/include/beast/core/static_string.hpp b/include/beast/core/static_string.hpp index a3ec8919d9..6a9ef1e6a1 100644 --- a/include/beast/core/static_string.hpp +++ b/include/beast/core/static_string.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WEBSOCKET_STATIC_STRING_HPP #define BEAST_WEBSOCKET_STATIC_STRING_HPP +#include #include #include #include @@ -329,7 +330,8 @@ static_string:: static_string(static_string const& s) { if(s.size() > N) - throw std::length_error("static_string overflow"); + throw detail::make_exception( + "static_string overflow", __FILE__, __LINE__); n_ = s.size(); Traits::copy(&s_[0], &s.s_[0], n_ + 1); } @@ -353,7 +355,8 @@ operator=(static_string const& s) -> static_string& { if(s.size() > N) - throw std::length_error("static_string overflow"); + throw detail::make_exception( + "static_string overflow", __FILE__, __LINE__); n_ = s.size(); Traits::copy(&s_[0], &s.s_[0], n_ + 1); return *this; @@ -391,7 +394,8 @@ at(size_type pos) -> reference { if(pos >= n_) - throw std::out_of_range("static_string::at"); + throw detail::make_exception( + "invalid pos", __FILE__, __LINE__); return s_[pos]; } @@ -402,7 +406,8 @@ at(size_type pos) const -> const_reference { if(pos >= n_) - throw std::out_of_range("static_string::at"); + throw detail::make_exception( + "static_string::at", __FILE__, __LINE__); return s_[pos]; } @@ -412,7 +417,8 @@ static_string:: resize(std::size_t n) { if(n > N) - throw std::length_error("static_string overflow"); + throw detail::make_exception( + "static_string overflow", __FILE__, __LINE__); n_ = n; s_[n_] = 0; } @@ -423,7 +429,8 @@ static_string:: resize(std::size_t n, CharT c) { if(n > N) - throw std::length_error("static_string overflow"); + throw detail::make_exception( + "static_string overflow", __FILE__, __LINE__); if(n > n_) Traits::assign(&s_[n_], n - n_, c); n_ = n; @@ -462,7 +469,8 @@ assign(CharT const* s) { auto const n = Traits::length(s); if(n > N) - throw std::out_of_range("too large"); + throw detail::make_exception( + "too large", __FILE__, __LINE__); n_ = n; Traits::copy(&s_[0], s, n_ + 1); } diff --git a/include/beast/http/impl/message.ipp b/include/beast/http/impl/message.ipp index 9a818cd874..3f7c056501 100644 --- a/include/beast/http/impl/message.ipp +++ b/include/beast/http/impl/message.ipp @@ -159,6 +159,8 @@ void prepare(message& msg, Options&&... options) { + using beast::detail::make_exception; + // VFALCO TODO static_assert(is_Body::value, "Body requirements not met"); @@ -174,16 +176,16 @@ prepare(message& msg, std::forward(options)...); if(msg.fields.exists("Connection")) - throw std::invalid_argument( - "prepare called with Connection field set"); + throw make_exception( + "prepare called with Connection field set", __FILE__, __LINE__); if(msg.fields.exists("Content-Length")) - throw std::invalid_argument( - "prepare called with Content-Length field set"); + throw make_exception( + "prepare called with Content-Length field set", __FILE__, __LINE__); if(token_list{msg.fields["Transfer-Encoding"]}.exists("chunked")) - throw std::invalid_argument( - "prepare called with Transfer-Encoding: chunked set"); + throw make_exception( + "prepare called with Transfer-Encoding: chunked set", __FILE__, __LINE__); if(pi.connection_value != connection::upgrade) { @@ -254,8 +256,8 @@ prepare(message& msg, // rfc7230 6.7. if(msg.version < 11 && token_list{ msg.fields["Connection"]}.exists("upgrade")) - throw std::invalid_argument( - "invalid version for Connection: upgrade"); + throw make_exception( + "invalid version for Connection: upgrade", __FILE__, __LINE__); } } // http diff --git a/include/beast/http/message.hpp b/include/beast/http/message.hpp index ebe1723841..007b48746d 100644 --- a/include/beast/http/message.hpp +++ b/include/beast/http/message.hpp @@ -246,6 +246,18 @@ struct message : header /// Default constructor message() = default; + /// Move constructor + message(message&&) = default; + + /// Copy constructor + message(message const&) = default; + + /// Move assignment + message& operator=(message&&) = default; + + /// Copy assignment + message& operator=(message const&) = default; + /** Construct a message from a header. Additional arguments, if any, are forwarded to @@ -281,8 +293,9 @@ struct message : header */ template::type, base_type>::value> + , class = typename std::enable_if< + ! std::is_convertible::type, base_type>::value>::type #endif > explicit @@ -303,7 +316,7 @@ struct message : header template::type, base_type>::value> + typename std::decay::type, base_type>::value>::type #endif > message(U&& u, V&& v) diff --git a/include/beast/version.hpp b/include/beast/version.hpp index 7d02e32931..cc71abf074 100644 --- a/include/beast/version.hpp +++ b/include/beast/version.hpp @@ -16,6 +16,6 @@ // #define BEAST_VERSION 100000 -#define BEAST_VERSION_STRING "1.0.0-b22" +#define BEAST_VERSION_STRING "1.0.0-b23" #endif diff --git a/include/beast/websocket/impl/stream.ipp b/include/beast/websocket/impl/stream.ipp index bd04db45a8..2e41924986 100644 --- a/include/beast/websocket/impl/stream.ipp +++ b/include/beast/websocket/impl/stream.ipp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/include/beast/websocket/option.hpp b/include/beast/websocket/option.hpp index d2864cdd28..4f009f9693 100644 --- a/include/beast/websocket/option.hpp +++ b/include/beast/websocket/option.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -186,7 +187,8 @@ struct message_type message_type(opcode op) { if(op != opcode::binary && op != opcode::text) - throw std::domain_error("bad opcode"); + throw beast::detail::make_exception( + "bad opcode", __FILE__, __LINE__); value = op; } }; @@ -277,6 +279,9 @@ struct read_buffer_size read_buffer_size(std::size_t n) : value(n) { + if(n < 8) + throw beast::detail::make_exception( + "read buffer size is too small", __FILE__, __LINE__); } }; #endif @@ -356,7 +361,8 @@ struct write_buffer_size : value(n) { if(n < 8) - throw std::domain_error("write buffer size is too small"); + throw beast::detail::make_exception( + "write buffer size is too small", __FILE__, __LINE__); } }; #endif diff --git a/include/beast/zlib/detail/deflate_stream.hpp b/include/beast/zlib/detail/deflate_stream.hpp index 7b367d3e45..45dbdb98b9 100644 --- a/include/beast/zlib/detail/deflate_stream.hpp +++ b/include/beast/zlib/detail/deflate_stream.hpp @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -893,14 +894,19 @@ doReset( if(windowBits == 8) windowBits = 9; + using beast::detail::make_exception; + if(level < 0 || level > 9) - throw std::invalid_argument{"invalid level"}; + throw make_exception( + "invalid level", __FILE__, __LINE__); if(windowBits < 8 || windowBits > 15) - throw std::invalid_argument{"invalid windowBits"}; + throw make_exception( + "invalid windowBits", __FILE__, __LINE__); if(memLevel < 1 || memLevel > MAX_MEM_LEVEL) - throw std::invalid_argument{"invalid memLevel"}; + throw make_exception( + "invalid memLevel", __FILE__, __LINE__); w_bits_ = windowBits; diff --git a/include/beast/zlib/detail/inflate_stream.hpp b/include/beast/zlib/detail/inflate_stream.hpp index c13d9428c9..5b748fbe37 100644 --- a/include/beast/zlib/detail/inflate_stream.hpp +++ b/include/beast/zlib/detail/inflate_stream.hpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -232,7 +233,8 @@ inflate_stream:: doReset(int windowBits) { if(windowBits < 8 || windowBits > 15) - throw std::domain_error("windowBits out of range"); + throw beast::detail::make_exception( + "windowBits out of range", __FILE__, __LINE__); w_.reset(windowBits); bi_.flush(); @@ -706,7 +708,8 @@ doWrite(z_params& zs, Flush flush, error_code& ec) case SYNC: default: - throw std::logic_error("stream error"); + throw beast::detail::make_exception( + "stream error", __FILE__, __LINE__); } } } @@ -932,8 +935,8 @@ inflate_table( auto const not_enough = [] { - throw std::logic_error( - "insufficient output size when inflating tables"); + throw beast::detail::make_exception( + "insufficient output size when inflating tables", __FILE__, __LINE__); }; // check available table space diff --git a/scripts/build-and-test.sh b/scripts/build-and-test.sh index 3c8ed47ef5..e62e93aa8f 100755 --- a/scripts/build-and-test.sh +++ b/scripts/build-and-test.sh @@ -40,6 +40,9 @@ elif [[ $(uname -s) == "Linux" ]]; then if ((${num_proc_units} < ${num_jobs})); then num_jobs=$num_proc_units fi + if [[ "${TRAVIS}" == "true" && ${NUM_PROCESSORS:=2} > ${num_jobs} ]]; then + num_jobs=$NUM_PROCESSORS + fi fi echo "using toolset: $CC" @@ -99,10 +102,10 @@ function run_autobahn_test_suite { # We need to wait a while so wstest can connect! sleep 5 + # Show the output (if any) as it is generated + tail -f nohup.out & cd scripts && wstest -m fuzzingclient cd .. - # Show the output - cat nohup.out rm nohup.out # Show what jobs are running jobs @@ -110,6 +113,7 @@ function run_autobahn_test_suite { sleep 5 # Kill it gracefully kill -INT %1 + kill -INT %2 # Wait for all the jobs to finish wait # Parse the test results, with python>=2.5<3 script @@ -135,9 +139,10 @@ if [[ $VARIANT == "coverage" ]]; then # Perform test if [[ $MAIN_BRANCH == "1" ]]; then run_tests_with_valgrind - run_autobahn_test_suite + # skip slow autobahn tests + #run_autobahn_test_suite else - echo "skipping autobahn tests for feature branch build" + echo "skipping autobahn/valgrind tests for feature branch build" run_tests fi diff --git a/test/http/message.cpp b/test/http/message.cpp index d5db86e08e..47216b236d 100644 --- a/test/http/message.cpp +++ b/test/http/message.cpp @@ -278,6 +278,19 @@ public: BEAST_EXPECT(m2.fields.exists("h")); } + void + testSpecialMembers() + { + response r1; + response r2{r1}; + response r3{std::move(r2)}; + r2 = r3; + r1 = std::move(r2); + [r1]() + { + }(); + } + void run() override { testMessage(); @@ -285,6 +298,7 @@ public: testFreeFunctions(); testPrepare(); testSwap(); + testSpecialMembers(); } }; diff --git a/test/websocket/stream.cpp b/test/websocket/stream.cpp index 084019ebeb..53a16bdd9e 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 ae4963243b..0519deb203 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,24 @@ 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(async_echo_server const&) = delete; + async_echo_server& operator=(async_echo_server const&) = delete; + + 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 +59,7 @@ public: ~async_echo_server() { + work_ = boost::none; error_code ec; ios_.dispatch( [&]{ acceptor_.close(ec); }); @@ -78,6 +67,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 +118,7 @@ private: { struct data { - bool log; + async_echo_server& server; int state = 0; boost::optional ep; stream ws; @@ -98,8 +127,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 +140,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,14 +182,17 @@ 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(write_buffer_size{64 * 1024}); run(); } @@ -289,10 +322,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; } } @@ -302,7 +335,7 @@ private: fail(error_code ec, std::string what) { if(log_) - std::cerr << what << ": " << + (*log_) << what << ": " << ec.message() << std::endl; } @@ -328,7 +361,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 636087b4c3..a4ddee49c2 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; + } }