Connect to Poloniex Push-API

I want to connect to the Poloniex Push API . On their page they write the following:

To use the push API, connect to wss: //api.poloniex.com and subscribe to the desired channel.

wss = WebSocket Secure -> Secure SSL

They also provide an example for Node.js and Autobahn | JS:

var autobahn = require('autobahn'); var wsuri = "wss://api.poloniex.com"; var connection = new autobahn.Connection({ url: wsuri, realm: "realm1" }); connection.onopen = function (session) { function marketEvent (args,kwargs) { console.log(args); } function tickerEvent (args,kwargs) { console.log(args); } function trollboxEvent (args,kwargs) { console.log(args); } session.subscribe('BTC_XMR', marketEvent); session.subscribe('ticker', tickerEvent); session.subscribe('trollbox', trollboxEvent); } connection.onclose = function () { console.log("Websocket connection closed"); } connection.open(); 

However, I do not want to use JavaScript, instead I use C ++. There is also an Autobahn-Library for C ++ called Autobahn | CPP I installed it and tried to run the sample subscriber code with a few changes (basically just a hard-coded address and port):

 #include <autobahn/autobahn.hpp> #include <boost/asio.hpp> #include <iostream> #include <memory> #include <tuple> void topic1(const autobahn::wamp_event& event) { std::cerr << "received event: " << event.argument<uint64_t>(0) << std::endl; } using namespace boost; using namespace boost::asio; using namespace boost::asio::ip; int main() { try { boost::asio::io_service io; boost::asio::ip::tcp::socket socket(io); bool debug = true; auto session = std::make_shared< autobahn::wamp_session<boost::asio::ip::tcp::socket, boost::asio::ip::tcp::socket>>(io, socket, socket, debug); boost::future<void> start_future; boost::future<void> join_future; boost::asio::ip::tcp::endpoint rawsocket_endpoint( boost::asio::ip::address::from_string("173.236.42.218"), 443/*8000=standard*/); socket.async_connect(rawsocket_endpoint, [&](boost::system::error_code ec) { if (!ec) { std::cerr << "connected to server" << std::endl; start_future = session->start().then([&](boost::future<bool> started) { if (started.get()) { std::cerr << "session started" << std::endl; join_future = session->join("realm1").then([&](boost::future<uint64_t> s) { std::cerr << "joined realm: " << s.get() << std::endl; session->subscribe("ticker", &topic1); }); } else { std::cerr << "failed to start session" << std::endl; io.stop(); } }); } else { std::cerr << "connect failed: " << ec.message() << std::endl; io.stop(); } } ); std::cerr << "starting io service" << std::endl; io.run(); std::cerr << "stopped io service" << std::endl; } catch (std::exception& e) { std::cerr << e.what() << std::endl; return 1; } return 0; } 

There are a few things to explain here: I found out the IP address 173.236.42.218, just ping api.poloniex.com.

Port 443 is a standard SSL port. I tried using the standard WAMP / WebSocket port, which is 8000, but the server does not accept this. 80 is also not accepted.

So, if I run the program, the output is as follows:

launch io service

connected to server

Then nothing happens. So the code should get stuck in session_start () where the WS handshake is done, which you can see when viewing wamp_session.ipp on line 80.

In my opinion, the problem is that the API wants to use a secure connection (ws s : //). It seems that this piece of code is not trying to create an SSL encrypted connection, and I don’t know how to tell the session that I need a secure one.

Change In this question, the Author says that Autobahn cannot handle mixed http / wamp servers, where you must first use the HTTP request before using the WebSocket protocol. I know that Poloniex uses such a mixed type, but I already tried to access the API using Autobahn | JS and there it works fine, and also sends an update request. So maybe this is a problem with CPP autorun?

Edit 2: If this is true, is it possible to send an Http-Update-Request and maybe even set up SSL encryption in the connection? I'm not sure, because maybe this will affect the library.

+5
source share
2 answers

No, no, this is not the last answer. Late or not, I believe this may be a bit more direct solution for you Bobface (and any others that have struggled with this). I am embarrassed to give this as it will potentially be used by competitors. But what life without competition !? Boring, that’s what. And what's more, I want someone in front of me to move me and send it, so come here! Be the change you want to see, right?

Below you will find an implementation using websocketpp and autobahn | cpp to connect to Poloniex push api. In this case, he will receive updates made in books for BTC_ETH.

Generally speaking, this is how you can use websocketpp and autobahn | cpp to connect to a secure web socket server that implements the WAMP protocol (also known as wss: //ip-address.com: port).

Hooray!

Includes:

 #include <autobahn/autobahn.hpp> #include <autobahn/wamp_websocketpp_websocket_transport.hpp> #include <websocketpp/config/asio_no_tls_client.hpp> #include <websocketpp/client.hpp> #include <boost/version.hpp> #include <iostream> #include <memory> #include <string> #include <tuple> 

Code:

 typedef websocketpp::client<websocketpp::config::asio_tls_client> client; typedef autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> websocket_transport; try { //std::cerr << "Connecting to realm: " << parameters->realm() << std::endl; boost::asio::io_service io; //bool debug = parameters->debug(); client ws_client; ws_client.init_asio(&io); ws_client.set_tls_init_handler([&](websocketpp::connection_hdl) { return websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv12_client); }); auto transport = std::make_shared < autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> >( ws_client, "wss://api.poloniex.com:443", true); // create a WAMP session that talks WAMP-RawSocket over TCP auto session = std::make_shared<autobahn::wamp_session>(io, true); transport->attach(std::static_pointer_cast<autobahn::wamp_transport_handler>(session)); // Make sure the continuation futures we use do not run out of scope prematurely. // Since we are only using one thread here this can cause the io service to block // as a future generated by a continuation will block waiting for its promise to be // fulfilled when it goes out of scope. This would prevent the session from receiving // responses from the router. boost::future<void> connect_future; boost::future<void> start_future; boost::future<void> join_future; boost::future<void> subscribe_future; connect_future = transport->connect().then([&](boost::future<void> connected) { try { connected.get(); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; io.stop(); return; } std::cerr << "transport connected" << std::endl; start_future = session->start().then([&](boost::future<void> started) { try { started.get(); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; io.stop(); return; } std::cerr << "session started" << std::endl; join_future = session->join("realm1").then([&](boost::future<uint64_t> joined) { try { std::cerr << "joined realm: " << joined.get() << std::endl; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; io.stop(); return; } subscribe_future = session->subscribe("BTC_ETH", &on_topic1).then([&] (boost::future<autobahn::wamp_subscription> subscribed) { try { std::cerr << "subscribed to topic: " << subscribed.get().id() << std::endl; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; io.stop(); return; } }); }); }); }); std::cerr << "starting io service" << std::endl; io.run(); std::cerr << "stopped io service" << std::endl; } catch (std::exception& e) { std::cerr << "exception: " << e.what() << std::endl; ret_var.successfully_ran = false; return ret_var; } 
+7
source

I know this is a rather late answer to your question, but it seems that the problem is that you are not updating the HTTP / Websocket when connecting to the remote server. The sample code that you use is configured using the rawsocket_endpoint transport, which in my opinion means that there is no HTTP Websocket update or Websocket encapsulation. I do not think your problem is with SSL.

To connect to Websocket connections, you should consider the AutobahnCPP example , which uses Websocketpp .

+1
source

Source: https://habr.com/ru/post/1239230/


All Articles