Open HartS opened 3 years ago
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!
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:
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.
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.
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.
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
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 );
});
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
@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?
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.