Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I open multiple WebSocket streams

I am trying to stream data from the Binance WebSocket API, I have it working for one symbol at a time.

if ("WebSocket" in window) {
            //open websocket
            var symbols = getSymbol();
            //console.log(symbols);

            symbols.forEach(function(entry) {
              console.log(entry);
            })

            var ws = new WebSocket("wss://stream.binance.com:9443/ws/btcusdt@miniTicker")

            ws.onopen = function() {
                console.log("Binance connected...");
            };

            ws.onmessage = function(evt) {
                var r_msg = evt.data;
                var jr_msg = JSON.parse(r_msg);   
            }

            ws.onclose = function() {
                console.log("Binance disconnected");
            }
        } else {
            alert("WebSocket is NOT supported");
        }

the line var symbols = getSymbol(); creates an array of 431 symbols, my logic (and what I am trying to achieve) is to add the new websocket() to the forEach and stream price data from all of the currency pairs.

I'm not sure if this is possible at all or what a better solution would be but I wish to stream and display live data from the api.

like image 509
Rajbir Avatar asked Jan 01 '19 17:01

Rajbir


1 Answers

Your idea about putting the new WebSocket() inside the for-each should work. However, I'm not sure if you are allowed to opening hundreds of web sockets from the same tab, and there could also be some performance issues related to it.

According to the API documentation, it is possible to open just one web socket which will send you data from a list of streams, or even just all streams. Just construct the URLs like this:

  • Specific streams: wss://stream.binance.com:9443/ws/stream1/stream2/stream3
  • All streams: wss://stream.binance.com:9443/ws/!miniTicker@arr

Here is a code sample that takes these things into consideration. By default this code uses the URL for all streams, but it also has the code (commented out) that uses specific streams.

  let streams = [
    "ethbtc@miniTicker","bnbbtc@miniTicker","wavesbtc@miniTicker","bchabcbtc@miniTicker",
    "bchsvbtc@miniTicker","xrpbtc@miniTicker","tusdbtc@miniTicker","eosbtc@miniTicker",
    "trxbtc@miniTicker","ltcbtc@miniTicker","xlmbtc@miniTicker","bcptbtc@miniTicker",
    "adabtc@miniTicker","zilbtc@miniTicker","xmrbtc@miniTicker","stratbtc@miniTicker",
    "zecbtc@miniTicker","qkcbtc@miniTicker","neobtc@miniTicker","dashbtc@miniTicker","zrxbtc@miniTicker"
  ];

  let trackedStreams = [];

  //let ws = new WebSocket("wss://stream.binance.com:9443/ws/" + streams.join('/'));
  let ws = new WebSocket("wss://stream.binance.com:9443/ws/!miniTicker@arr");

  ws.onopen = function() {
      console.log("Binance connected...");
  };

  ws.onmessage = function(evt) {
    try {
      let msgs = JSON.parse(evt.data);
      if (Array.isArray(msgs)) {
        for (let msg of msgs) {
          handleMessage(msg);
        }
      } else {
        handleMessage(msgs)
      }
    } catch (e) {
      console.log('Unknown message: ' + evt.data, e);
    }
  }

  ws.onclose = function() {
    console.log("Binance disconnected");
  }

  function handleMessage(msg) {
    const stream = msg.s;
    if (trackedStreams.indexOf(stream) === -1) {
      document.getElementById('streams').innerHTML += '<br/>' + stream + ': <span id="stream_' + stream + '"></span>';
      trackedStreams.push(stream);
      document.getElementById('totalstreams').innerText = trackedStreams.length;
    }

    document.getElementById('stream_' + stream).innerText = msg.v;
  }
<span id="totalstreams"></span> streams tracked<br/>
Total traded base asset volume:<br/>
<div id="streams"></div>
like image 64
Anders Carstensen Avatar answered Nov 18 '22 15:11

Anders Carstensen