mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
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
This commit is contained in:
@@ -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"
|
||||
|
||||
11
CHANGELOG.md
11
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
|
||||
|
||||
@@ -253,7 +253,8 @@ private:
|
||||
reference
|
||||
dereference(C<sizeof...(Bn)> const&) const
|
||||
{
|
||||
throw std::logic_error("invalid iterator");
|
||||
throw detail::make_exception<std::logic_error>(
|
||||
"invalid iterator", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
@@ -269,7 +270,8 @@ private:
|
||||
void
|
||||
increment(C<sizeof...(Bn)> const&)
|
||||
{
|
||||
throw std::logic_error("invalid iterator");
|
||||
throw detail::make_exception<std::logic_error>(
|
||||
"invalid iterator", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
@@ -310,7 +312,8 @@ private:
|
||||
--iter<I>();
|
||||
return;
|
||||
}
|
||||
throw std::logic_error("invalid iterator");
|
||||
throw detail::make_exception<std::logic_error>(
|
||||
"invalid iterator", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
@@ -78,6 +80,18 @@ struct repeat_tuple<0, T>
|
||||
using type = std::tuple<>;
|
||||
};
|
||||
|
||||
template<class Exception>
|
||||
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
|
||||
|
||||
|
||||
@@ -524,8 +524,8 @@ basic_streambuf<Allocator>::basic_streambuf(
|
||||
, alloc_size_(alloc_size)
|
||||
{
|
||||
if(alloc_size <= 0)
|
||||
throw std::invalid_argument(
|
||||
"basic_streambuf: invalid alloc_size");
|
||||
throw detail::make_exception<std::invalid_argument>(
|
||||
"invalid alloc_size", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_IMPL_BUFFERS_ADAPTER_IPP
|
||||
#define BEAST_IMPL_BUFFERS_ADAPTER_IPP
|
||||
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
@@ -413,8 +414,8 @@ buffers_adapter<MutableBufferSequence>::prepare(std::size_t n) ->
|
||||
}
|
||||
}
|
||||
if(n > 0)
|
||||
throw std::length_error(
|
||||
"no space in buffers_adapter");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"no space", __FILE__, __LINE__);
|
||||
return mutable_buffers_type{*this};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_IMPL_STATIC_STREAMBUF_IPP
|
||||
#define BEAST_IMPL_STATIC_STREAMBUF_IPP
|
||||
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
@@ -295,7 +296,8 @@ static_streambuf::prepare(std::size_t n) ->
|
||||
mutable_buffers_type
|
||||
{
|
||||
if(n > static_cast<std::size_t>(end_ - out_))
|
||||
throw std::length_error("no space in streambuf");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"no space in streambuf", __FILE__, __LINE__);
|
||||
last_ = out_ + n;
|
||||
return mutable_buffers_type{out_, n};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_WEBSOCKET_STATIC_STRING_HPP
|
||||
#define BEAST_WEBSOCKET_STATIC_STRING_HPP
|
||||
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
@@ -329,7 +330,8 @@ static_string<N, CharT, Traits>::
|
||||
static_string(static_string<M, CharT, Traits> const& s)
|
||||
{
|
||||
if(s.size() > N)
|
||||
throw std::length_error("static_string overflow");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"static_string overflow", __FILE__, __LINE__);
|
||||
n_ = s.size();
|
||||
Traits::copy(&s_[0], &s.s_[0], n_ + 1);
|
||||
}
|
||||
@@ -353,7 +355,8 @@ operator=(static_string<M, CharT, Traits> const& s) ->
|
||||
static_string&
|
||||
{
|
||||
if(s.size() > N)
|
||||
throw std::length_error("static_string overflow");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"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<std::out_of_range>(
|
||||
"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<std::out_of_range>(
|
||||
"static_string::at", __FILE__, __LINE__);
|
||||
return s_[pos];
|
||||
}
|
||||
|
||||
@@ -412,7 +417,8 @@ static_string<N, CharT, Traits>::
|
||||
resize(std::size_t n)
|
||||
{
|
||||
if(n > N)
|
||||
throw std::length_error("static_string overflow");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"static_string overflow", __FILE__, __LINE__);
|
||||
n_ = n;
|
||||
s_[n_] = 0;
|
||||
}
|
||||
@@ -423,7 +429,8 @@ static_string<N, CharT, Traits>::
|
||||
resize(std::size_t n, CharT c)
|
||||
{
|
||||
if(n > N)
|
||||
throw std::length_error("static_string overflow");
|
||||
throw detail::make_exception<std::length_error>(
|
||||
"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<std::out_of_range>(
|
||||
"too large", __FILE__, __LINE__);
|
||||
n_ = n;
|
||||
Traits::copy(&s_[0], s, n_ + 1);
|
||||
}
|
||||
|
||||
@@ -159,6 +159,8 @@ void
|
||||
prepare(message<isRequest, Body, Fields>& msg,
|
||||
Options&&... options)
|
||||
{
|
||||
using beast::detail::make_exception;
|
||||
|
||||
// VFALCO TODO
|
||||
static_assert(is_Body<Body>::value,
|
||||
"Body requirements not met");
|
||||
@@ -174,16 +176,16 @@ prepare(message<isRequest, Body, Fields>& msg,
|
||||
std::forward<Options>(options)...);
|
||||
|
||||
if(msg.fields.exists("Connection"))
|
||||
throw std::invalid_argument(
|
||||
"prepare called with Connection field set");
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"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<std::invalid_argument>(
|
||||
"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<std::invalid_argument>(
|
||||
"prepare called with Transfer-Encoding: chunked set", __FILE__, __LINE__);
|
||||
|
||||
if(pi.connection_value != connection::upgrade)
|
||||
{
|
||||
@@ -254,8 +256,8 @@ prepare(message<isRequest, Body, Fields>& 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<std::invalid_argument>(
|
||||
"invalid version for Connection: upgrade", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
} // http
|
||||
|
||||
@@ -246,6 +246,18 @@ struct message : header<isRequest, Fields>
|
||||
/// 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<isRequest, Fields>
|
||||
*/
|
||||
template<class U
|
||||
#if ! GENERATING_DOCS
|
||||
, class = typename std::enable_if<! std::is_convertible<
|
||||
typename std::decay<U>::type, base_type>::value>
|
||||
, class = typename std::enable_if<
|
||||
! std::is_convertible<typename
|
||||
std::decay<U>::type, base_type>::value>::type
|
||||
#endif
|
||||
>
|
||||
explicit
|
||||
@@ -303,7 +316,7 @@ struct message : header<isRequest, Fields>
|
||||
template<class U, class V
|
||||
#if ! GENERATING_DOCS
|
||||
,class = typename std::enable_if<! std::is_convertible<
|
||||
typename std::decay<U>::type, base_type>::value>
|
||||
typename std::decay<U>::type, base_type>::value>::type
|
||||
#endif
|
||||
>
|
||||
message(U&& u, V&& v)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <beast/core/prepare_buffers.hpp>
|
||||
#include <beast/core/static_streambuf.hpp>
|
||||
#include <beast/core/stream_concepts.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/endian/buffers.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <beast/websocket/rfc6455.hpp>
|
||||
#include <beast/websocket/detail/decorator.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
@@ -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<std::invalid_argument>(
|
||||
"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<std::invalid_argument>(
|
||||
"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<std::invalid_argument>(
|
||||
"write buffer size is too small", __FILE__, __LINE__);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <beast/zlib/zlib.hpp>
|
||||
#include <beast/zlib/detail/ranges.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <cstdint>
|
||||
@@ -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<std::invalid_argument>(
|
||||
"invalid level", __FILE__, __LINE__);
|
||||
|
||||
if(windowBits < 8 || windowBits > 15)
|
||||
throw std::invalid_argument{"invalid windowBits"};
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"invalid windowBits", __FILE__, __LINE__);
|
||||
|
||||
if(memLevel < 1 || memLevel > MAX_MEM_LEVEL)
|
||||
throw std::invalid_argument{"invalid memLevel"};
|
||||
throw make_exception<std::invalid_argument>(
|
||||
"invalid memLevel", __FILE__, __LINE__);
|
||||
|
||||
w_bits_ = windowBits;
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <beast/zlib/detail/bitstream.hpp>
|
||||
#include <beast/zlib/detail/ranges.hpp>
|
||||
#include <beast/zlib/detail/window.hpp>
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -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<std::domain_error>(
|
||||
"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<std::logic_error>(
|
||||
"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<std::logic_error>(
|
||||
"insufficient output size when inflating tables", __FILE__, __LINE__);
|
||||
};
|
||||
|
||||
// check available table space
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -278,6 +278,19 @@ public:
|
||||
BEAST_EXPECT(m2.fields.exists("h"));
|
||||
}
|
||||
|
||||
void
|
||||
testSpecialMembers()
|
||||
{
|
||||
response<string_body> r1;
|
||||
response<string_body> r2{r1};
|
||||
response<string_body> r3{std::move(r2)};
|
||||
r2 = r3;
|
||||
r1 = std::move(r2);
|
||||
[r1]()
|
||||
{
|
||||
}();
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testMessage();
|
||||
@@ -285,6 +298,7 @@ public:
|
||||
testFreeFunctions();
|
||||
testPrepare();
|
||||
testSwap();
|
||||
testSpecialMembers();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
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<std::thread> thread_;
|
||||
boost::optional<boost::asio::io_service::work> 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<endpoint_type> ep;
|
||||
stream<socket_type> 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<class... Args>
|
||||
explicit
|
||||
Peer(bool log, socket_type&& sock, Args&&... args)
|
||||
: d_(std::make_shared<data>(log,
|
||||
Peer(async_echo_server& server,
|
||||
socket_type&& sock, Args&&... args)
|
||||
: d_(std::make_shared<data>(server,
|
||||
std::forward<socket_type>(sock),
|
||||
std::forward<Args>(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)};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,17 +8,27 @@
|
||||
#include "websocket_async_echo_server.hpp"
|
||||
#include "websocket_sync_echo_server.hpp"
|
||||
#include <beast/test/sig_wait.hpp>
|
||||
#include <iostream>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user