我无法构建 beast websocket 示例中提供的示例之一
i cannot build one of the examples provided in the beast websocket example
我的代码:
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/strand.hpp>
#include <boost/thread/thread.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <cstdlib>
#include <fstream>
#include <jsoncpp/json/value.h>
#include <jsoncpp/json/json.h>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include<unistd.h>
#include<sys/types.h>
using namespace std;
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio; // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
//------------------------------------------------------------------------------
// Report a failure
void
fail(beast::error_code ec, char const* what)
{
std::cerr << what << ": " << ec.message() << "\n";
}
// Sends a WebSocket message and prints the response
class session : public std::enable_shared_from_this<session>
{
tcp::resolver resolver_;
websocket::stream<beast::tcp_stream> ws_;
beast::flat_buffer buffer_;
std::string host_;
Json::Value json;
public:
// Resolver and socket require an io_context
explicit
session(net::io_context& ioc)
: resolver_(net::make_strand(ioc))
, ws_(net::make_strand(ioc))
{
}
// Start the asynchronous operation
void
run(
char const* host,
char const* port,
Json::Value text)
{
// Save these for later
host_ = host;
json = text;
// Look up the domain name
resolver_.async_resolve(
host,
port,
beast::bind_front_handler(
&session::on_resolve,
shared_from_this()));
}
void
on_resolve(
beast::error_code ec,
tcp::resolver::results_type results)
{
if(ec)
return fail(ec, "resolve");
// Set the timeout for the operation
beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));
// Make the connection on the IP address we get from a lookup
beast::get_lowest_layer(ws_).async_connect(
results,
beast::bind_front_handler(
&session::on_connect,
shared_from_this()));
}
void
on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type ep)
{
if(ec)
return fail(ec, "connect");
// Turn off the timeout on the tcp_stream, because
// the websocket stream has its own timeout system.
beast::get_lowest_layer(ws_).expires_never();
// Set suggested timeout settings for the websocket
ws_.set_option(
websocket::stream_base::timeout::suggested(
beast::role_type::client));
// Set a decorator to change the User-Agent of the handshake
ws_.set_option(websocket::stream_base::decorator(
[](websocket::request_type& req)
{
req.set(http::field::user_agent,
std::string(BOOST_BEAST_VERSION_STRING) +
" websocket-client-async");
}));
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host_ += ':' + std::to_string(ep.port());
// Perform the websocket handshake
ws_.async_handshake(host_, "/",
beast::bind_front_handler(
&session::on_handshake,
shared_from_this()));
}
std::string
Json_to_string(const Json::Value &json)
{
std::string result;
Json::StreamWriterBuilder wbuilder;
wbuilder["indentation"] = ""; // Optional
result = Json::writeString(wbuilder, json);
return result;
}
void
on_handshake(beast::error_code ec)
{
if(ec)
return fail(ec, "handshake");
// Send the message
std::string jsonner = Json_to_string(json);
auto jsontxt = std::make_shared<std::string>(jsonner);
ws_.async_write(
boost::asio::buffer(*jsontxt),
beast::bind_front_handler(
&session::on_write,
shared_from_this(),jsontxt));
}
void
on_write(
beast::error_code ec,
std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "write");
// Read a message into our buffer
ws_.async_read(
buffer_,
beast::bind_front_handler(
&session::on_read,
shared_from_this()));
}
void
on_read(
beast::error_code ec,
std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "read");
// Close the WebSocket connection
ws_.async_close(websocket::close_code::normal,
beast::bind_front_handler(
&session::on_close,
shared_from_this()));
}
void
on_close(beast::error_code ec)
{
if(ec)
return fail(ec, "close");
// If we get here then the connection is closed gracefully
// The make_printable() function helps print a ConstBufferSequence
std::cout << beast::make_printable(buffer_.data()) << std::endl;
}
};
//------------------------------------------------------------------------------
int main(int argc, char** argv)
{
// Check command line arguments.
if(argc != 4)
{
std::cerr <<
"Usage: websocket-client-async <host> <port> <text>\n" <<
"Example:\n" <<
" websocket-client-async echo.websocket.org 80 \"Hello, world!\"\n";
return EXIT_FAILURE;
}
// auto const host = argv[1];
// auto const port = argv[1];
// auto const text = argv[1];
ifstream file("details.json");
Json::Value actualjson;
Json::Reader jsonreader;
jsonreader.parse(file,actualjson);
// The io_context is required for all I/O
net::io_context context;
// Launch the asynchronous operation
std::make_shared<session>(context)->run("stream.binance.com","9443", actualjson);
// Run the I/O service. The call will return when
// the socket is closed.
context.run();
return EXIT_SUCCESS;
}
完整错误in a gist,缩写:
In file included from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/boost/beast/core/detail/bind_handler.hpp: In instantiation of ‘void boost::beast::...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/async_base.hpp:353:13: required from ‘void boost::beast::async_...
/usr/include/boost/beast/websocket/impl/write.hpp:167:59: required from ‘void boost::beast::w...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: error: no match for call to ‘(std...
235 | std::mem_fn(h_)(
| ~~~~~~~~~~~~~~~^
236 | detail::get<I>(std::move(args_))...,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
237 | std::forward<Ts>(ts)...);
| ~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/system/error_code.hpp:19,
from /usr/include/boost/beast/core/error.hpp:14,
from /usr/include/boost/beast/core/detail/bind_handler.hpp:13,
from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/c++/9/functional:110:2: note: candidate: ‘template<class ... _Args> decltype (std:...
110 | operator()(_Args&&... __args) const
| ^~~~~~~~
/usr/include/c++/9/functional:110:2: note: template argument deduction/substitution failed:
/usr/include/c++/9/functional: In substitution of ‘template<class ... _Args> decltype (std::__i...
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: required from ‘void boost::beas...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/async_base.hpp:353:13: required from ‘void boost::beast::async_...
/usr/include/boost/beast/websocket/impl/write.hpp:167:59: required from ‘void boost::beast::w...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/c++/9/functional:113:27: error: no matching function for call to ‘__invoke(void (s...
113 | -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/tuple:41,
from /usr/include/c++/9/functional:54,
from /usr/include/boost/system/error_code.hpp:19,
from /usr/include/boost/beast/core/error.hpp:14,
from /usr/include/boost/beast/core/detail/bind_handler.hpp:13,
from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/c++/9/bits/invoke.h:89:5: note: candidate: ‘template<class _Callable, class ... _A...
89 | __invoke(_Callable&& __fn, _Args&&... __args)
| ^~~~~~~~
/usr/include/c++/9/bits/invoke.h:89:5: note: template argument deduction/substitution failed:...
/usr/include/c++/9/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args...
/usr/include/c++/9/functional:113:27: required by substitution of ‘template<class ... _Args> ...
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: required from ‘void boost::beas...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/async_base.hpp:353:13: required from ‘void boost::beast::async_...
/usr/include/boost/beast/websocket/impl/write.hpp:167:59: required from ‘void boost::beast::w...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/c++/9/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_res...
In file included from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/boost/beast/core/detail/bind_handler.hpp: In instantiation of ‘void boost::beast::...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:224:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/asio/bind_executor.hpp:414:61: required from ‘typename std::result_of<T(Ar...
/usr/include/boost/asio/detail/executor_function.hpp:91:15: required from ‘static void boost:...
/usr/include/boost/asio/detail/executor_function.hpp:66:50: [ skipping 8 instantiation contex...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: error: no match for call to ‘(std...
235 | std::mem_fn(h_)(
| ~~~~~~~~~~~~~~~^
236 | detail::get<I>(std::move(args_))...,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
237 | std::forward<Ts>(ts)...);
| ~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/system/error_code.hpp:19,
from /usr/include/boost/beast/core/error.hpp:14,
from /usr/include/boost/beast/core/detail/bind_handler.hpp:13,
from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/c++/9/functional:110:2: note: candidate: ‘template<class ... _Args> decltype (std:...
110 | operator()(_Args&&... __args) const
| ^~~~~~~~
/usr/include/c++/9/functional:110:2: note: template argument deduction/substitution failed:
/usr/include/c++/9/functional: In substitution of ‘template<class ... _Args> decltype (std::__i...
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: required from ‘void boost::beas...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:224:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/asio/bind_executor.hpp:414:61: required from ‘typename std::result_of<T(Ar...
/usr/include/boost/asio/detail/executor_function.hpp:91:15: [ skipping 9 instantiation contex...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/c++/9/functional:113:27: error: no matching function for call to ‘__invoke(void (s...
113 | -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/tuple:41,
from /usr/include/c++/9/functional:54,
from /usr/include/boost/system/error_code.hpp:19,
from /usr/include/boost/beast/core/error.hpp:14,
from /usr/include/boost/beast/core/detail/bind_handler.hpp:13,
from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/c++/9/bits/invoke.h:89:5: note: candidate: ‘template<class _Callable, class ... _A...
89 | __invoke(_Callable&& __fn, _Args&&... __args)
| ^~~~~~~~
/usr/include/c++/9/bits/invoke.h:89:5: note: template argument deduction/substitution failed:...
/usr/include/c++/9/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args...
/usr/include/c++/9/functional:113:27: required by substitution of ‘template<class ... _Args> ...
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: required from ‘void boost::beas...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:224:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/asio/bind_executor.hpp:414:61: [ skipping 10 instantiation contexts, use -...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/c++/9/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_res...
make[2]: *** [CMakeFiles/hftbot.dir/build.make:83: CMakeFiles/hftbot.dir/src/main.cpp.o] Error ...
make[1]: *** [CMakeFiles/Makefile2:116: CMakeFiles/hftbot.dir/all] Error 2
所以我正在尝试向 binance 发送 json 请求,以通过 websocket 流式传输市场更新。
币安 api 文档:https://binance-docs.github.io/apidocs/spot/en/#websocket-market-streams
我的details.json长相:
{
"method": "SUBSCRIBE",
"params":
[
"btcusdt@depth"
],
"id": 1
}
我不知道这里发生了什么。请帮助我并提前谢谢!
这里:
auto jsontxt = std::make_shared<std::string>(jsonner);
ws_.async_write(
boost::asio::buffer(*jsontxt),
beast::bind_front_handler(
&session::on_write,
shared_from_this(),jsontxt));
您绑定了一个额外的参数jsontxt
。这个想法没问题:您想将 json 文本缓冲区的生命周期延长到写入操作的持续时间。但是 on_write
不接受额外的 jsontxt
参数。
您可以修复从
void on_write(beast::error_code ec, std::size_t bytes_transferred) {
至
void on_write(std::shared_ptr<std::string> /*jsontxt*/,
beast::error_code ec, std::size_t bytes_transferred) {
确实可以编译。但是,它有点笨拙,扩展性不好(您还要将多少参数绑定到各种处理程序中?)。我们可以做得更好吗?
做得更好
请注意 session
class 已经使用共享所有权:
class session : public std::enable_shared_from_this<session>
接下来,请注意您已经使用shared_from_this()
(而不是仅this
)在处理程序中共享该所有权。
这意味着如果您让 jsontxt
成为 class 的成员,您将 已经 拥有 life-time 保证,但效率更高并且没有使用额外绑定参数的笨拙。
事实上,您可以将字符串化的 JSON 直接存储在 run()
:
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/strand.hpp>
#include <boost/thread/thread.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <cstdlib>
#include <fstream>
#include <json/json.h>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <sys/types.h>
#include <unistd.h>
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio; // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
//------------------------------------------------------------------------------
// Report a failure
void
fail(beast::error_code ec, char const* what)
{
std::cerr << what << ": " << ec.message() << "\n";
}
// Sends a WebSocket message and prints the response
class session : public std::enable_shared_from_this<session>
{
tcp::resolver resolver_;
websocket::stream<beast::tcp_stream> ws_;
beast::flat_buffer buffer_;
std::string host_;
std::string message_text_;
public:
// Resolver and socket require an io_context
explicit
session(net::io_context& ioc)
: resolver_(net::make_strand(ioc))
, ws_(net::make_strand(ioc))
{
}
// Start the asynchronous operation
void
run(
char const* host,
char const* port,
Json::Value message)
{
// Save these for later
host_ = host;
message_text_ = Json_to_string(message);
// Look up the domain name
resolver_.async_resolve(
host,
port,
beast::bind_front_handler(
&session::on_resolve,
shared_from_this()));
}
void
on_resolve(
beast::error_code ec,
tcp::resolver::results_type results)
{
if(ec)
return fail(ec, "resolve");
// Set the timeout for the operation
beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));
// Make the connection on the IP address we get from a lookup
beast::get_lowest_layer(ws_).async_connect(
results,
beast::bind_front_handler(
&session::on_connect,
shared_from_this()));
}
void
on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type ep)
{
if(ec)
return fail(ec, "connect");
// Turn off the timeout on the tcp_stream, because
// the websocket stream has its own timeout system.
beast::get_lowest_layer(ws_).expires_never();
// Set suggested timeout settings for the websocket
ws_.set_option(
websocket::stream_base::timeout::suggested(
beast::role_type::client));
// Set a decorator to change the User-Agent of the handshake
ws_.set_option(websocket::stream_base::decorator(
[](websocket::request_type& req)
{
req.set(http::field::user_agent,
std::string(BOOST_BEAST_VERSION_STRING) +
" websocket-client-async");
}));
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host_ += ':' + std::to_string(ep.port());
// Perform the websocket handshake
ws_.async_handshake(host_, "/",
beast::bind_front_handler(
&session::on_handshake,
shared_from_this()));
}
std::string Json_to_string(const Json::Value& json) {
Json::StreamWriterBuilder wbuilder;
wbuilder["indentation"] = ""; // Optional
return Json::writeString(wbuilder, json);
}
void
on_handshake(beast::error_code ec)
{
if(ec) {
return fail(ec, "handshake");
}
// Send the message
ws_.async_write(
net::buffer(message_text_),
beast::bind_front_handler(&session::on_write, shared_from_this()));
}
void on_write(beast::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "write");
// Read a message into our buffer
ws_.async_read(
buffer_,
beast::bind_front_handler(
&session::on_read,
shared_from_this()));
}
void
on_read(
beast::error_code ec,
std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "read");
// Close the WebSocket connection
ws_.async_close(websocket::close_code::normal,
beast::bind_front_handler(
&session::on_close,
shared_from_this()));
}
void
on_close(beast::error_code ec)
{
if(ec)
return fail(ec, "close");
// If we get here then the connection is closed gracefully
// The make_printable() function helps print a ConstBufferSequence
std::cout << beast::make_printable(buffer_.data()) << std::endl;
}
};
//------------------------------------------------------------------------------
int main()
{
// auto const host = argv[1];
// auto const port = argv[1];
// auto const text = argv[1];
std::ifstream file("details.json");
Json::Value actualjson;
Json::Reader jsonreader;
jsonreader.parse(file,actualjson);
// The io_context is required for all I/O
net::io_context context;
// Launch the asynchronous operation
std::make_shared<session>(context)->run("stream.binance.com", "9443",
actualjson);
// Run the I/O service. The call will return when
// the socket is closed.
context.run();
return EXIT_SUCCESS;
}
我的代码:
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/strand.hpp>
#include <boost/thread/thread.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <cstdlib>
#include <fstream>
#include <jsoncpp/json/value.h>
#include <jsoncpp/json/json.h>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include<unistd.h>
#include<sys/types.h>
using namespace std;
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio; // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
//------------------------------------------------------------------------------
// Report a failure
void
fail(beast::error_code ec, char const* what)
{
std::cerr << what << ": " << ec.message() << "\n";
}
// Sends a WebSocket message and prints the response
class session : public std::enable_shared_from_this<session>
{
tcp::resolver resolver_;
websocket::stream<beast::tcp_stream> ws_;
beast::flat_buffer buffer_;
std::string host_;
Json::Value json;
public:
// Resolver and socket require an io_context
explicit
session(net::io_context& ioc)
: resolver_(net::make_strand(ioc))
, ws_(net::make_strand(ioc))
{
}
// Start the asynchronous operation
void
run(
char const* host,
char const* port,
Json::Value text)
{
// Save these for later
host_ = host;
json = text;
// Look up the domain name
resolver_.async_resolve(
host,
port,
beast::bind_front_handler(
&session::on_resolve,
shared_from_this()));
}
void
on_resolve(
beast::error_code ec,
tcp::resolver::results_type results)
{
if(ec)
return fail(ec, "resolve");
// Set the timeout for the operation
beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));
// Make the connection on the IP address we get from a lookup
beast::get_lowest_layer(ws_).async_connect(
results,
beast::bind_front_handler(
&session::on_connect,
shared_from_this()));
}
void
on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type ep)
{
if(ec)
return fail(ec, "connect");
// Turn off the timeout on the tcp_stream, because
// the websocket stream has its own timeout system.
beast::get_lowest_layer(ws_).expires_never();
// Set suggested timeout settings for the websocket
ws_.set_option(
websocket::stream_base::timeout::suggested(
beast::role_type::client));
// Set a decorator to change the User-Agent of the handshake
ws_.set_option(websocket::stream_base::decorator(
[](websocket::request_type& req)
{
req.set(http::field::user_agent,
std::string(BOOST_BEAST_VERSION_STRING) +
" websocket-client-async");
}));
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host_ += ':' + std::to_string(ep.port());
// Perform the websocket handshake
ws_.async_handshake(host_, "/",
beast::bind_front_handler(
&session::on_handshake,
shared_from_this()));
}
std::string
Json_to_string(const Json::Value &json)
{
std::string result;
Json::StreamWriterBuilder wbuilder;
wbuilder["indentation"] = ""; // Optional
result = Json::writeString(wbuilder, json);
return result;
}
void
on_handshake(beast::error_code ec)
{
if(ec)
return fail(ec, "handshake");
// Send the message
std::string jsonner = Json_to_string(json);
auto jsontxt = std::make_shared<std::string>(jsonner);
ws_.async_write(
boost::asio::buffer(*jsontxt),
beast::bind_front_handler(
&session::on_write,
shared_from_this(),jsontxt));
}
void
on_write(
beast::error_code ec,
std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "write");
// Read a message into our buffer
ws_.async_read(
buffer_,
beast::bind_front_handler(
&session::on_read,
shared_from_this()));
}
void
on_read(
beast::error_code ec,
std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "read");
// Close the WebSocket connection
ws_.async_close(websocket::close_code::normal,
beast::bind_front_handler(
&session::on_close,
shared_from_this()));
}
void
on_close(beast::error_code ec)
{
if(ec)
return fail(ec, "close");
// If we get here then the connection is closed gracefully
// The make_printable() function helps print a ConstBufferSequence
std::cout << beast::make_printable(buffer_.data()) << std::endl;
}
};
//------------------------------------------------------------------------------
int main(int argc, char** argv)
{
// Check command line arguments.
if(argc != 4)
{
std::cerr <<
"Usage: websocket-client-async <host> <port> <text>\n" <<
"Example:\n" <<
" websocket-client-async echo.websocket.org 80 \"Hello, world!\"\n";
return EXIT_FAILURE;
}
// auto const host = argv[1];
// auto const port = argv[1];
// auto const text = argv[1];
ifstream file("details.json");
Json::Value actualjson;
Json::Reader jsonreader;
jsonreader.parse(file,actualjson);
// The io_context is required for all I/O
net::io_context context;
// Launch the asynchronous operation
std::make_shared<session>(context)->run("stream.binance.com","9443", actualjson);
// Run the I/O service. The call will return when
// the socket is closed.
context.run();
return EXIT_SUCCESS;
}
完整错误in a gist,缩写:
In file included from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/boost/beast/core/detail/bind_handler.hpp: In instantiation of ‘void boost::beast::...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/async_base.hpp:353:13: required from ‘void boost::beast::async_...
/usr/include/boost/beast/websocket/impl/write.hpp:167:59: required from ‘void boost::beast::w...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: error: no match for call to ‘(std...
235 | std::mem_fn(h_)(
| ~~~~~~~~~~~~~~~^
236 | detail::get<I>(std::move(args_))...,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
237 | std::forward<Ts>(ts)...);
| ~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/system/error_code.hpp:19,
from /usr/include/boost/beast/core/error.hpp:14,
from /usr/include/boost/beast/core/detail/bind_handler.hpp:13,
from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/c++/9/functional:110:2: note: candidate: ‘template<class ... _Args> decltype (std:...
110 | operator()(_Args&&... __args) const
| ^~~~~~~~
/usr/include/c++/9/functional:110:2: note: template argument deduction/substitution failed:
/usr/include/c++/9/functional: In substitution of ‘template<class ... _Args> decltype (std::__i...
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: required from ‘void boost::beas...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/async_base.hpp:353:13: required from ‘void boost::beast::async_...
/usr/include/boost/beast/websocket/impl/write.hpp:167:59: required from ‘void boost::beast::w...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/c++/9/functional:113:27: error: no matching function for call to ‘__invoke(void (s...
113 | -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/tuple:41,
from /usr/include/c++/9/functional:54,
from /usr/include/boost/system/error_code.hpp:19,
from /usr/include/boost/beast/core/error.hpp:14,
from /usr/include/boost/beast/core/detail/bind_handler.hpp:13,
from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/c++/9/bits/invoke.h:89:5: note: candidate: ‘template<class _Callable, class ... _A...
89 | __invoke(_Callable&& __fn, _Args&&... __args)
| ^~~~~~~~
/usr/include/c++/9/bits/invoke.h:89:5: note: template argument deduction/substitution failed:...
/usr/include/c++/9/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args...
/usr/include/c++/9/functional:113:27: required by substitution of ‘template<class ... _Args> ...
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: required from ‘void boost::beas...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/async_base.hpp:353:13: required from ‘void boost::beast::async_...
/usr/include/boost/beast/websocket/impl/write.hpp:167:59: required from ‘void boost::beast::w...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/c++/9/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_res...
In file included from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/boost/beast/core/detail/bind_handler.hpp: In instantiation of ‘void boost::beast::...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:224:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/asio/bind_executor.hpp:414:61: required from ‘typename std::result_of<T(Ar...
/usr/include/boost/asio/detail/executor_function.hpp:91:15: required from ‘static void boost:...
/usr/include/boost/asio/detail/executor_function.hpp:66:50: [ skipping 8 instantiation contex...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: error: no match for call to ‘(std...
235 | std::mem_fn(h_)(
| ~~~~~~~~~~~~~~~^
236 | detail::get<I>(std::move(args_))...,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
237 | std::forward<Ts>(ts)...);
| ~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/system/error_code.hpp:19,
from /usr/include/boost/beast/core/error.hpp:14,
from /usr/include/boost/beast/core/detail/bind_handler.hpp:13,
from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/c++/9/functional:110:2: note: candidate: ‘template<class ... _Args> decltype (std:...
110 | operator()(_Args&&... __args) const
| ^~~~~~~~
/usr/include/c++/9/functional:110:2: note: template argument deduction/substitution failed:
/usr/include/c++/9/functional: In substitution of ‘template<class ... _Args> decltype (std::__i...
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: required from ‘void boost::beas...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:224:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/asio/bind_executor.hpp:414:61: required from ‘typename std::result_of<T(Ar...
/usr/include/boost/asio/detail/executor_function.hpp:91:15: [ skipping 9 instantiation contex...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/c++/9/functional:113:27: error: no matching function for call to ‘__invoke(void (s...
113 | -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/tuple:41,
from /usr/include/c++/9/functional:54,
from /usr/include/boost/system/error_code.hpp:19,
from /usr/include/boost/beast/core/error.hpp:14,
from /usr/include/boost/beast/core/detail/bind_handler.hpp:13,
from /usr/include/boost/beast/core/bind_handler.hpp:14,
from /usr/include/boost/beast/core/async_base.hpp:14,
from /usr/include/boost/beast/core.hpp:15,
from /home/user/Desktop/HFTBOT/src/main.cpp:1:
/usr/include/c++/9/bits/invoke.h:89:5: note: candidate: ‘template<class _Callable, class ... _A...
89 | __invoke(_Callable&& __fn, _Args&&... __args)
| ^~~~~~~~
/usr/include/c++/9/bits/invoke.h:89:5: note: template argument deduction/substitution failed:...
/usr/include/c++/9/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args...
/usr/include/c++/9/functional:113:27: required by substitution of ‘template<class ... _Args> ...
/usr/include/boost/beast/core/detail/bind_handler.hpp:235:24: required from ‘void boost::beas...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:224:9: required from ‘void boost::beast...
/usr/include/boost/beast/core/detail/bind_handler.hpp:258:9: required from ‘void boost::beast...
/usr/include/boost/asio/bind_executor.hpp:414:61: [ skipping 10 instantiation contexts, use -...
/usr/include/boost/beast/websocket/impl/write.hpp:140:16: required from ‘boost::beast::websoc...
/usr/include/boost/beast/websocket/impl/write.hpp:459:9: required from ‘void boost::beast::we...
/usr/include/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_resu...
/usr/include/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost...
/usr/include/boost/beast/websocket/impl/write.hpp:772:39: required from ‘typename boost::asio...
/home/user/Desktop/HFTBOT/src/main.cpp:153:44: required from here
/usr/include/c++/9/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_res...
make[2]: *** [CMakeFiles/hftbot.dir/build.make:83: CMakeFiles/hftbot.dir/src/main.cpp.o] Error ...
make[1]: *** [CMakeFiles/Makefile2:116: CMakeFiles/hftbot.dir/all] Error 2
所以我正在尝试向 binance 发送 json 请求,以通过 websocket 流式传输市场更新。 币安 api 文档:https://binance-docs.github.io/apidocs/spot/en/#websocket-market-streams
我的details.json长相:
{
"method": "SUBSCRIBE",
"params":
[
"btcusdt@depth"
],
"id": 1
}
我不知道这里发生了什么。请帮助我并提前谢谢!
这里:
auto jsontxt = std::make_shared<std::string>(jsonner);
ws_.async_write(
boost::asio::buffer(*jsontxt),
beast::bind_front_handler(
&session::on_write,
shared_from_this(),jsontxt));
您绑定了一个额外的参数jsontxt
。这个想法没问题:您想将 json 文本缓冲区的生命周期延长到写入操作的持续时间。但是 on_write
不接受额外的 jsontxt
参数。
您可以修复从
void on_write(beast::error_code ec, std::size_t bytes_transferred) {
至
void on_write(std::shared_ptr<std::string> /*jsontxt*/,
beast::error_code ec, std::size_t bytes_transferred) {
确实可以编译。但是,它有点笨拙,扩展性不好(您还要将多少参数绑定到各种处理程序中?)。我们可以做得更好吗?
做得更好
请注意 session
class 已经使用共享所有权:
class session : public std::enable_shared_from_this<session>
接下来,请注意您已经使用shared_from_this()
(而不是仅this
)在处理程序中共享该所有权。
这意味着如果您让 jsontxt
成为 class 的成员,您将 已经 拥有 life-time 保证,但效率更高并且没有使用额外绑定参数的笨拙。
事实上,您可以将字符串化的 JSON 直接存储在 run()
:
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/strand.hpp>
#include <boost/thread/thread.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <cstdlib>
#include <fstream>
#include <json/json.h>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <sys/types.h>
#include <unistd.h>
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio; // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
//------------------------------------------------------------------------------
// Report a failure
void
fail(beast::error_code ec, char const* what)
{
std::cerr << what << ": " << ec.message() << "\n";
}
// Sends a WebSocket message and prints the response
class session : public std::enable_shared_from_this<session>
{
tcp::resolver resolver_;
websocket::stream<beast::tcp_stream> ws_;
beast::flat_buffer buffer_;
std::string host_;
std::string message_text_;
public:
// Resolver and socket require an io_context
explicit
session(net::io_context& ioc)
: resolver_(net::make_strand(ioc))
, ws_(net::make_strand(ioc))
{
}
// Start the asynchronous operation
void
run(
char const* host,
char const* port,
Json::Value message)
{
// Save these for later
host_ = host;
message_text_ = Json_to_string(message);
// Look up the domain name
resolver_.async_resolve(
host,
port,
beast::bind_front_handler(
&session::on_resolve,
shared_from_this()));
}
void
on_resolve(
beast::error_code ec,
tcp::resolver::results_type results)
{
if(ec)
return fail(ec, "resolve");
// Set the timeout for the operation
beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));
// Make the connection on the IP address we get from a lookup
beast::get_lowest_layer(ws_).async_connect(
results,
beast::bind_front_handler(
&session::on_connect,
shared_from_this()));
}
void
on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type ep)
{
if(ec)
return fail(ec, "connect");
// Turn off the timeout on the tcp_stream, because
// the websocket stream has its own timeout system.
beast::get_lowest_layer(ws_).expires_never();
// Set suggested timeout settings for the websocket
ws_.set_option(
websocket::stream_base::timeout::suggested(
beast::role_type::client));
// Set a decorator to change the User-Agent of the handshake
ws_.set_option(websocket::stream_base::decorator(
[](websocket::request_type& req)
{
req.set(http::field::user_agent,
std::string(BOOST_BEAST_VERSION_STRING) +
" websocket-client-async");
}));
// Update the host_ string. This will provide the value of the
// Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
host_ += ':' + std::to_string(ep.port());
// Perform the websocket handshake
ws_.async_handshake(host_, "/",
beast::bind_front_handler(
&session::on_handshake,
shared_from_this()));
}
std::string Json_to_string(const Json::Value& json) {
Json::StreamWriterBuilder wbuilder;
wbuilder["indentation"] = ""; // Optional
return Json::writeString(wbuilder, json);
}
void
on_handshake(beast::error_code ec)
{
if(ec) {
return fail(ec, "handshake");
}
// Send the message
ws_.async_write(
net::buffer(message_text_),
beast::bind_front_handler(&session::on_write, shared_from_this()));
}
void on_write(beast::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "write");
// Read a message into our buffer
ws_.async_read(
buffer_,
beast::bind_front_handler(
&session::on_read,
shared_from_this()));
}
void
on_read(
beast::error_code ec,
std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "read");
// Close the WebSocket connection
ws_.async_close(websocket::close_code::normal,
beast::bind_front_handler(
&session::on_close,
shared_from_this()));
}
void
on_close(beast::error_code ec)
{
if(ec)
return fail(ec, "close");
// If we get here then the connection is closed gracefully
// The make_printable() function helps print a ConstBufferSequence
std::cout << beast::make_printable(buffer_.data()) << std::endl;
}
};
//------------------------------------------------------------------------------
int main()
{
// auto const host = argv[1];
// auto const port = argv[1];
// auto const text = argv[1];
std::ifstream file("details.json");
Json::Value actualjson;
Json::Reader jsonreader;
jsonreader.parse(file,actualjson);
// The io_context is required for all I/O
net::io_context context;
// Launch the asynchronous operation
std::make_shared<session>(context)->run("stream.binance.com", "9443",
actualjson);
// Run the I/O service. The call will return when
// the socket is closed.
context.run();
return EXIT_SUCCESS;
}