I`m trying to connect to Kraken websocket API.But i got "The WebSocket handshake was declined by the remote peer" error.
I`ve wrote a wrapper class for websocket and rest api client of exchanges.It works well with Binance websocket APIs,but Kraken websocket connection was unsuccessful.
I have tried diffrent type of tls(ssl::context ctx_webSocket{ ssl::context::tlsv13_client };) verions too, but the result was same.
class Exchange {
public:
Exchange(std::string name, const std::string& http_host) :m_name(std::move(name)) {
init_http(http_host);
}
void init_http(std::string const& host) {
const auto results{ resolver.resolve(host,"443") };
get_lowest_layer(stream).connect(results);
if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str()))
{
boost::system::error_code ec{ static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category() };
throw boost::system::system_error{ ec };
}
stream.handshake(ssl::stream_base::client);
}
void init_webSocket(std::string const& host, std::string const& port, std::string const& target) {
auto const results = resolver_webSocket.resolve(host, port);
net::connect(ws.next_layer().next_layer(), results.begin(), results.end());
ws.next_layer().handshake(ssl::stream_base::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-coro");
}));
ws.handshake(host, target.c_str());
}
void read_Socket() {
ws.read(buffer);
}
void write_Socket(const std::string& text) {
ws.write(net::buffer(text));
}
std::string get_socket_data() {
return beast::buffers_to_string(buffer.data());
}
void buffer_clear() {
buffer.clear();
}
void webSocket_close() {
ws.close(websocket::close_code::none);
}
private:
// HTTP REQUEST SET //
std::string m_name;
net::io_context ioc;
ssl::context ctx{ ssl::context::tlsv12_client };
tcp::resolver resolver{ ioc };
Stream stream{ ioc, ctx };
// WEB SOCKET SET //
std::string m_web_socket_host;
std::string m_web_socket_port;
beast::flat_buffer buffer;
net::io_context ioc_webSocket;
ssl::context ctx_webSocket{ ssl::context::tlsv13_client };
tcp::resolver resolver_webSocket{ ioc_webSocket };
websocket::stream<beast::ssl_stream<tcp::socket>> ws{ ioc_webSocket, ctx_webSocket };
};
int main()
{
Exchange kraken{ "kraken","api.kraken.com" };
try
{
kraken.init_webSocket("ws.kraken.com", "443", "/");
while (true)
{
kraken.read_Socket();
std::cout << kraken.get_socket_data();
return 1;
kraken.buffer_clear();
}
kraken.webSocket_close();
}
catch (std::exception const& e)
{
std::cerr << "Error: " << e.what() << std::endl;
}
}
SOLVED. I have found out where the problem is. Before websocket handshake, have to set the SNI host name, here below is the working test code.