I’m trying to write some C++ code that will open a websocket connection to the Binance API. I’m stuck, and wondering if anyone has any suggestions or sample code for me.
I’m running on RedHat Linux and am using the websocketpp, boost, asio, and openssl open-source libraries – the most current, stable version of each. At compile time, I’m linking -lboost_system ,-lpthread, -ljsoncpp, -lcrypto, and -lssl.
I’ve been able to successfully compile and link the code but, at run time, I’m told: “[2023-07-14 18:45:55] [error] Server handshake response error: websocketpp.processor:20 (Invalid HTTP status.)
[2023-07-14 18:45:55] [info] asio async_shutdown error: asio.ssl.stream:1 (stream truncated)”.
I think the issue may be that I’m not implementing, or correctly implementing, TLS.
Following is my code. In this listing, only the class Configuration (instantiated as myConfiguration) is of my own making. All else is based on the open-source libraries listed above. In this context, all myConfiguration does is supply the binance endpoint via the method GetEndpointWebStream(). I’ve been testing with the endpoint wss://stream.binance.us:9443/ws/btcusd@depth.
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include
#include
#include “classConfiguration.h”
typedef websocketpp::clientwebsocketpp::config::asio_tls_client client;
void tls_init_handler(websocketpp::connection_hdl hdl) {
client::connection_ptr connection = websocketpp::lib::static_pointer_cast<websocketpp::connectionwebsocketpp::config::asio_tls_client>(hdl.lock());
boost::asio::ssl::context& tlsContext = connection->get_socket().next_layer().get_context();
// Configure the SSL context as needed
tlsContext.set_verify_mode(boost::asio::ssl::verify_none);
tlsContext.set_options(boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::no_sslv3 |
boost::asio::ssl::context::no_tlsv1 |
boost::asio::ssl::context::no_tlsv1_1 |
boost::asio::ssl::context::single_dh_use);
// Set certificates, trust store, etc.
// Perform any other necessary TLS initialization
}
int main(int argc, char** argv) {
Configuration thisConfiguration(argc, argv);
client websocketClient;
websocketpp::lib::asio::io_context ioContext;
websocketClient.init_asio(&ioContext);
// Set TLS-related settings
websocketClient.clear_access_channels(websocketpp::log::alevel::all);
// Set handlers for WebSocket events
websocketClient.set_open_handler([](websocketpp::connection_hdl) {
std::cout << "WebSocket connection opened" << std::endl;
});
websocketClient.set_message_handler([](websocketpp::connection_hdl, client::message_ptr msg) {
std::cout << "Received message: " << msg->get_payload() << std::endl;
});
websocketClient.set_close_handler([](websocketpp::connection_hdl) {
std::cout << "WebSocket connection closed" << std::endl;
});
websocketClient.set_tls_init_handler(&tls_init_handler);
websocketpp::lib::error_code errorCode;
client::connection_ptr connection = websocketClient.get_connection(thisConfiguration.GetEndpointWebStream(), errorCode);
if (errorCode) {
std::cout << "Could not create connection: " << errorCode.message() << std::endl;
return 1;
}
websocketClient.connect(connection);
// Run the event loop
websocketClient.run();
return 0;
}