20 #include <test/jtx/WSClient.h>
22 #include <ripple/json/json_reader.h>
23 #include <ripple/json/to_string.h>
24 #include <ripple/protocol/jss.h>
25 #include <ripple/server/Port.h>
26 #include <boost/beast/core/multi_buffer.hpp>
27 #include <boost/beast/websocket.hpp>
35 #include <ripple/beast/unit_test.h>
56 boost::asio::ip::tcp::endpoint
62 auto const ps = v2 ?
"ws2" :
"ws";
71 using namespace boost::asio::ip;
72 if(pp.
ip && pp.
ip->is_unspecified())
73 *pp.
ip = pp.
ip->is_v6() ? address{address_v6::loopback()} : address{address_v4::loopback()};
74 return { *pp.
ip, *pp.
port };
76 Throw<std::runtime_error>(
"Missing WebSocket port");
80 template <
class ConstBuffers>
85 using boost::asio::buffer;
86 using boost::asio::buffer_size;
89 buffer_copy(buffer(&s[0], s.
size()), b);
93 boost::asio::io_service
ios_;
95 boost::asio::io_service::work>
work_;
99 boost::beast::websocket::stream<boost::asio::ip::tcp::socket&>
ws_;
100 boost::beast::multi_buffer
rb_;
122 ws_.async_close({}, strand_.wrap([&](error_code ec) {
145 ws_.handshake_ex(ep.address().to_string() +
147 [&](boost::beast::websocket::request_type &req)
149 for (auto const& h : headers)
150 req.set(h.first, h.second);
154 this, std::placeholders::_1)));
172 using boost::asio::buffer;
173 using namespace std::chrono_literals;
181 jp[jss::method] = cmd;
182 jp[jss::jsonrpc] =
"2.0";
183 jp[jss::ripplerpc] =
"2.0";
187 jp[jss::command] = cmd;
189 ws_.write_some(
true, buffer(s));
195 return jval[jss::type] == jss::response;
200 jv->removeMember(jss::type);
201 if ((*jv).isMember(jss::status) &&
202 (*jv)[jss::status] == jss::error)
205 ret[jss::result] = *jv;
206 if ((*jv).isMember(jss::error))
207 ret[jss::error] = (*jv)[jss::error];
208 ret[jss::status] = jss::error;
211 if ((*jv).isMember(jss::status) &&
212 (*jv).isMember(jss::result))
213 (*jv)[jss::result][jss::status] =
220 boost::optional<Json::Value>
227 [&]{ return ! msgs_.empty(); }))
229 m = std::move(
msgs_.back());
232 return std::move(m->
jv);
235 boost::optional<Json::Value>
245 for (auto it = msgs_.begin();
246 it != msgs_.end(); ++it)
261 return std::move(m->jv);
275 if(ec == boost::beast::websocket::error::closed)
284 auto m = std::make_shared<msg>(
293 this, std::placeholders::_1)));
310 return std::make_unique<WSClientImpl>(cfg, v2, rpc_version, headers);