Better comunication with Bitcoinity's websocket

I think I have to send 3 messages to the websocket
to initialise it. In response, it seems to send the last
ticker price reasonably quickly, compared to earlier
when it was just waiting for the next available transaction
before notifying me.
This commit is contained in:
King_DuckZ 2022-05-14 06:58:49 +02:00
commit d80908da4e
10 changed files with 436 additions and 62 deletions

View file

@ -15,8 +15,7 @@
* along with duckticker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "websocket_reader.hpp"
#include <simdjson.h>
#include "bitcoinity_reader.hpp"
#include <wrenpp/vm_fun.hpp>
#include <wrenpp/def_configuration.hpp>
#include <wrenpp/callback_manager.hpp>
@ -53,7 +52,6 @@ class App {
var the_app = App.new("USD", "kraken")
)script";
class TickerPrice {
public:
TickerPrice() = default;
@ -80,67 +78,39 @@ private:
TickerPrice ticker_price_bitoinity (std::string_view currency, std::string_view exchange) {
static const TickerPrice error_price {0.0, "", ""};
duck::WebsocketReader websocket{"bitcoinity.org",
"80",
"/webs_bridge/websocket",
duck::BitcoinityReader bitcoinity{
std::string{duck::WebsocketReader::BeastVersionString} + " websocket-client-coro",
R"({"topic":"webs:markets_)" + std::string{exchange} + "_" +
std::string{currency} + R"(","event":"phx_join","payload":{},"ref":"3"})"
exchange,
currency
};
simdjson::ondemand::parser parser;
{
simdjson::padded_string body = websocket.read();
std::cout << body << '\n';
if (body.size() == 0)
return error_price;
simdjson::ondemand::document doc = parser.iterate(body);
do {
//possible values I observed:
// {"event":"new_msg","payload":{"data":{"currency":"EUR","exchange_name":"paymium","last":28363.44}},"ref":null,"topic":"webs:markets"}
// {"event":"new_msg","payload":{"data":{"currency":"USD","depth":{"price":30071,"type":1,"volume":-1.4123},"exchange_name":"bitfinex"}},"ref":null,"topic":"webs:markets_bitfinex_USD"}
// {"event":"new_msg","payload":{"data":{"currency":"USD","exchange_name":"bitfinex","trade":{"amount":0.0486,"date":1652471682,"exchange_name":"bitfinex","price":30072}}},"ref":null,"topic":"webs:markets_bitfinex_USD"}
if (doc["event"].get_string().value() != "phx_reply" or doc["payload"]["status"].get_string().value() != "ok")
return error_price;
}
{
double price_out;
std::string currency_out;
std::string exchange_out;
do {
simdjson::padded_string body = websocket.read();
std::cout << body << '\n';
simdjson::ondemand::document doc = parser.iterate(body);
auto payload_result = doc["payload"];
if (payload_result.error())
return error_price;
simdjson::ondemand::object payload = payload_result;
auto data_result = payload["data"];
if (data_result.error())
return error_price;
simdjson::ondemand::object data = data_result;
std::optional<double> price;
auto msg = bitcoinity.read();
simdjson::error_code price_error;
if (not data["depth"].error()) {
price_error = data["depth"]["price"].get(price_out);
}
else if (not data["trade"].error()) {
price_error = data["trade"]["price"].get(price_out);
}
else if (not data["depth_shot"].error()) {
continue;
}
if (msg.payload.has_key("data", "depth_shot"))
continue;
std::string_view currency_out_view, exchange_out_view;
const auto currency_error = data["currency"].get(currency_out_view);
const auto exchange_error = data["exchange_name"].get(exchange_out_view);
if ((price = msg.payload.get_double("data", "last")))
price_out = *price;
else if ((price = msg.payload.get_double("data", "depth", "price")))
price_out = *price;
else if ((price = msg.payload.get_double("data", "trade", "price")))
price_out = *price;
else
continue; //keep trying, sometimes I get a message like:
//{"event":"new_msg","payload":{"data":{"connected_count":1355}},"ref":null,"topic":"webs:markets"}
if (price_error or currency_error or exchange_error)
return error_price;
currency_out = currency_out_view;
exchange_out = exchange_out_view;
} while (false);
return {price_out, std::move(currency_out), std::move(exchange_out)};
}
std::string_view currency_out = msg.payload.get_string_or_empty("data", "currency");
std::string_view exchange_out = msg.payload.get_string_or_empty("data", "exchange_name");
return {price_out, std::string(currency_out), std::string(exchange_out)};
} while (true);
}
void ticker_price_bitcoinity_wren (wren::VM& vm) {