Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation on running in browser with webpack #144

Open
HartS opened this issue Sep 14, 2021 · 8 comments
Open

Documentation on running in browser with webpack #144

HartS opened this issue Sep 14, 2021 · 8 comments

Comments

@HartS
Copy link

HartS commented Sep 14, 2021

Hi, I'm interested in getting this running in my browser (I know I can get around the cors issues with CORS-proxy, so I'm not too worried about that). I'm wondering if you've documented any steps to get it built with Webpack though.

@tiagosiebler
Copy link
Owner

Hi there - the only docs on that so far are here:
https://github.com/tiagosiebler/binance#browser-usage

If you include the bundled js file with a script tag on a page, you'll have a global variable called binanceapi that should expose all parts of the library. Hope that helps you get started - would appreciate if you can help improve the docs once you've spent time with it!

@HartS
Copy link
Author

HartS commented Sep 15, 2021

Hi @tiagosiebler I'd be happy to contribute some docs and fixes as necessary.. I'm trying to get websocket data collection working.

So it appears there are some issues here due to the websocket implementation by isomorphic-ws for the browser not having a ping() method. I'm setting up the websocket in the browser with the following code:

const wsClient = new binanceapi.WebsocketClient({
  beautify: true,
  wsUrl: 'wss://stream.binance.com:9443'
});

// receive raw events
wsClient.on('message', (data) => {
  console.log('raw message received ', JSON.stringify(data, null, 2));
});


wsClient.on('open', (data) => {
  console.log('connection opened open:', data.wsKey, data.ws.target.url);
});

// receive formatted events with beautified keys. Any "known" floats stored in strings as parsed as floats.
wsClient.on('formattedMessage', (data) => {
  console.log('formattedMessage: ', data);
});

// read response to command sent via WS stream (e.g LIST_SUBSCRIPTIONS)
wsClient.on('reply', (data) => {
  console.log('log reply: ', JSON.stringify(data, null, 2));
});

// receive notification when a ws connection is reconnecting automatically
wsClient.on('reconnecting', (data) => {
  console.log('ws automatically reconnecting.... ', data?.wsKey );
});

// receive notification that a reconnection completed successfully (e.g use REST to check for missing data)
wsClient.on('reconnected', (data) => {
  console.log('ws has reconnected ', data?.wsKey );
});

wsClient.subscribeSpotTrades('BTC/USDT');

Notes:

  • I have to set wsUrl when instantiating the wsClient, or else is else it tries to open a websocket connection to localhost
  • You don't actually need to use a cors-proxy for the websocket connection :) So that makes things a bit easier.

So I was able to get a readable browser package that I could insert debug logs into by changing https://github.com/tiagosiebler/binance/blob/master/webpack/webpack.config.js#L16 from production to development

What I found was that ws.ping is failing because it doesn't exist on the ws object.

Debugging this is really painstaking though as I have to replace the silly loglevel messages I'm interested in with console.log to get output (I haven't tried actually setting up the logger with silly logging because I assume it would be too noisy... does this sound right?). If you have any guidance on how to set things up so logging works better for debugging it'd be helpful. I may see if I can monkey patch ping/pong onto the websocket object so that it works as expected as well.

@tiagosiebler
Copy link
Owner

tiagosiebler commented Sep 15, 2021

Debugging this is really painstaking though as I have to replace the silly loglevel messages I'm interested in with console.log to get output (I haven't tried actually setting up the logger with silly logging because I assume it would be too noisy... does this sound right?). If you have any guidance on how to set things up so logging works better for debugging it'd be helpful. I may see if I can monkey patch ping/pong onto the websocket object so that it works as expected as well.

Thanks for spending time on this! You can override the default logger by passing your own implementation into the second parameter of the WebsocketClient constructor. There's an example in the websocket demo in the readme:
https://github.com/tiagosiebler/binance#websockets

const logger = {
  ...DefaultLogger,
  silly: (...params) => { console.log(...params); },
};

const wsClient = new WebsocketClient({
  api_key: key,
  api_secret: secret,
  beautify: true,
}, logger);

Something like this should enable the silly logger again.

What I found was that ws.ping is failing because it doesn't exist on the ws object.

It must be this part that's throwing:
https://github.com/tiagosiebler/binance/blob/master/src/websocket-client.ts#L216-L217

I'm not sure yet how to approach this. If I remember right, the browser websocket implementation doesn't provide ways to send the ping/pong frames: https://stackoverflow.com/questions/10585355/sending-websocket-ping-pong-frame-from-browser

The main purpose of this logic is to send something upstream at an interval and start a timer. If the server doesn't send a reply downstream before the timer expires, we assume the connection dropped and being the resurrection process (by first closing the existing connection):
https://github.com/tiagosiebler/binance/blob/master/src/websocket-client.ts#L341-L344

This works well in node where those functions trigger pong frames, but an alternative will be needed for browsers where those functions don't exist... anything to trigger some kind of server response on the same stream. If it's reliable enough, it could even replace the ping/pong heartbeats.

@HartS
Copy link
Author

HartS commented Sep 16, 2021

Thanks for the detailed response @tiagosiebler ! I may try to get together a PR working to resolve the issues if I have time over the next couple of weeks.

I'm wondering how you'd feel about removing isomorphic-ws as a dependency (it hasn't been updated in 3 years) with ws on node, and either using the native browser WebSocket or a different library for the browser bundle?

I haven't investigated this too much yet, I just noticed isomorphic-ws doesn't support ping/pong, or terminate, so it might defeat the purpose of using it in the first place if there are a lot of things that have to be handled differently.

@tiagosiebler
Copy link
Owner

Thanks for the detailed response @tiagosiebler ! I may try to get together a PR working to resolve the issues if I have time over the next couple of weeks.

That'd be great, thanks!

I'm wondering how you'd feel about removing isomorphic-ws as a dependency (it hasn't been updated in 3 years) with ws on node, and either using the native browser WebSocket or a different library for the browser bundle?

I'm open to alternatives as long as they don't introduce unnecessary dependencies.

I haven't investigated this too much yet, I just noticed isomorphic-ws doesn't support ping/pong, or terminate, so it might defeat the purpose of using it in the first place if there are a lot of things that have to be handled differently.

The ping/pong limitation is actually due to the websocket implementation in browsers. This library just points to it, if you're in a browser environment, but the limitation comes from the browser API:
https://stackoverflow.com/questions/10585355/sending-websocket-ping-pong-frame-from-browser

@tiagosiebler tiagosiebler added docs and removed bug labels May 1, 2022
@mr-smit
Copy link

mr-smit commented Sep 14, 2022

How to build browser binanceapi.js

mkdir binance && cd binance
git clone https://github.com/tiagosiebler/binance.git .
npm install
npm install webpack
npm run build
npm run pack

Go to dist/ directory where binanceapi.js is located.

because its compiled as module, you need to import it in your project like this:
import './binanceapi.js';

or in html
<script type="module" src="binanceapi.js"></script>

it will create a binanceapi object which you can use like this

        // or MainClient
	let binance = new binanceapi.USDMClient({
	  api_key: API_KEY,
	  api_secret: API_SECRET,
	});
	
	let balance = await binance.getBalance();
	for(let i in balance){
		if (balance[i].asset == "USDT"){
			console.log("Balance USDT: ", balance[i].balance);
			break;
		}
	}
	
	
	
	let wsClient = new binanceapi.WebsocketClient({
	  api_key: API_KEY,
	  api_secret: API_SECRET,
	  beautify: true,
	  disableHeartbeat: true // browser does not support Ping/Pong
	});
	
	wsClient.subscribeUsdFuturesUserDataStream();
	
	wsClient.subscribeSymbolBookTicker('BTCUSDT', 'usdm');
	
	wsClient.on('open', (data) => {
	  console.log('Connected !');
	});

	wsClient.on('message', (data) => {
	  console.log('raw message received ', JSON.stringify(data, null, 2));
	});

	wsClient.on('formattedMessage', (data) => {
	  console.log('formattedMessage: ', data);
	});

	wsClient.on('reply', (data) => {
	  console.log('log reply: ', JSON.stringify(data, null, 2));
	});

	wsClient.on('error', (data) => {
	  console.log('ws saw error ', data?.wsKey );
	});

@tiagosiebler
Copy link
Owner

How to build browser binanceapi.js

mkdir binance && cd binance
git clone https://github.com/tiagosiebler/binance.git .
npm install
npm install webpack
npm run build
npm run pack

Go to dist/ directory where binanceapi.js is located.

No need to npm install webpack, it's included in the dev dependencies so it will automatically get installed when you run npm install

@Sandr0oo
Copy link

Sandr0oo commented Feb 14, 2023

@tiagosiebler Help please. I want to use your SDK in the browser, but I get an error when I try to install it. How do I solve the problem?
изображение

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants