Проблема
Я пытаюсь создать веб-сокет для подключения к довольно загруженному каналу сервера, используя C++ и Boost::Beast. На данный момент все, что он делает, это считывает данные, странным образом декодирует их и распечатывает.
У меня есть настройка, но по какой-то причине, когда я меняю настройку сокета, чтобы использовать статические методы и переменные в моем классе connection
, это дает эту странную ошибку:
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument
Что я сделал до сих пор
Поиск этой проблемы в Интернете, несколько потоки, похоже, намекают на то, что это проблема многопоточности. Дело в том, что мое программное обеспечение является однопоточным.
Все, что он делает до сих пор, это следующее:
main.cpp
#include "OkexSocket.h"
int main() {
const std::string host = "real.okex.com";
auto const port = "8443";
auto const path = "/ws/v3";
OkexSocket::init_socket(host, port, path);
OkexSocket::send_subscribe(R"({"op": "subscribe", "args": ["swap/depth_l2_tbt:ETH-USDT-SWAP","swap/depth_l2_tbt:BTC-USDT-SWAP"]})");
OkexSocket::receive_data();
}
и вот как я реализовал эти функции:
Сначала я создаю соединение через веб-сокет в OkexSocket::init_socket
и сохраняю поток для последующего использования:
void OkexSocket::init_socket(const string& host, const string& port, const string& path) {
net::io_context ioc;
tcp::resolver resolver{ ioc };
ssl::context ctx { ssl::context::sslv23 };
ctx.set_verify_mode(ssl::verify_none);
auto* socket = new websocket::stream<ssl::stream<tcp::socket>>{ioc, ctx };
net::connect(beast::get_lowest_layer(*socket), resolver.resolve(host, port));
// SSL handshake
socket->next_layer().handshake(ssl::stream_base::client);
socket->handshake(host + ":" + port, path);
socket_logger->info("Client is connected...");
OkexSocket::s = socket;
}
Затем я вызываю OkexSocket::send_subscribe
, который в основном однострочный:
void OkexSocket::send_subscribe(const string &message) {
// send request to the websocket
s->write(net::buffer(message));
}
а затем я подаю поток данных так:
void OkexSocket::receive_data() {
std::vector<uint8_t> in, out;
auto in_buffer = net::dynamic_buffer(in);
int i = 0;
while (true) {
socket->read(in_buffer);
// decode and print in_buffer...
in_buffer.consume(in_buffer.size());
if (i++ == 300) {
break;
}
}
}
Примечания и выводы...
да, я знаю, что есть утечка памяти, с
OkexSocket::s
. Меня это не волнует, поскольку оно должно существовать на протяжении всей жизни программы и инициализируется только один раз. Поскольку система вернет это пространство после того, как код будет выполнен, мне все равно. Однако открыт для критики по структуре кода.Если вы добавите весь этот код в
main()
, он отлично заработает... не знаю, почему
Я довольно новичок в boost::beast
, и я не нашел много ресурсов, чтобы помочь с этим :/ Я честно думаю, что документация предполагает кого-то, кто является профессионалом в boost
и сетях, что, к сожалению, не так. Если все, что вы можете предоставить, это ресурсы, чтобы помочь мне, я был бы очень рад.
receive_data
, это проблема. Я думаю, что буферы должны пережить соединения. Попробуйте сделать свой буфер членом вашего класса. Ваша ссылка - person lakeweb   schedule 23.02.2021