ShrimpyWsClient js code sample
Hi guys,
A code sample in JS for how to connect to the Websocket using ShrimpyWsClient would be useful.
I am running the following code without success:
let errorHandler = (error) => { console.log(error); };
let client = new Shrimpy.ShrimpyWsClient(errorHandler);
const subscribeData = {
"type": "subscribe",
"pair": "btc-usd",
"exchange": "coinbasepro",
"channel": "trade"
};
const unsubscribeData = {
"type": "unsubscribe",
"pair": "btc-usd",
"exchange": "coinbasepro",
"channel": "trade"
};
let handler = (msg) => { console.log(msg); };
client.connect();
client.subscribe(subscribeData, handler);
client.unsubscribe(unsubscribeData);
client.forceDisconnect();
Error log:
(node:49263) UnhandledPromiseRejectionWarning: Error: WebSocket is not open: readyState 0 (CONNECTING)
Hi jsappme, We are planning to make some improvements to the library and add some js code examples as well. Are there any other examples you would be interested in?
I am also having issues establishing a JS websocket utilizing the example given. Rather than an error I get an undefined connection - when are you going to provide a working example?
The issue with the example is that client.connect() is an asynchronous call but the method does not return a promise, and the example does not explain you must wait for the socket connection to be stablished (wsClient.getReadyState() === 1) before you can subscribe to consume data.
This is the code to get around the issue.
const initWSClientAndSubscribe = () => {
return this
.createWSClient()
.then((wsClient: ShrimpyWsClient) => {
wsClient.connect()
const waitUntilConnected = (): Promise<void> => {
if (wsClient.getReadyState() === 1) {
return Promise.resolve()
}
console.debug("waiting for socket connection ...")
return sleep(1).then(() => waitUntilConnected())
}
return waitUntilConnected()
.then(() => {
tradingPairs.forEach((pair: ITradingPair) => {
const req: ISubscriptionRequest = createBBOSubscribeReq(Exchange.BINANCE, pair)
wsClient.subscribe(req, (data: IWebsocketMessage) => {
console.debug(data)
})
})
})
})
.catch(this.errorHandler)
}
const sleep = (seconds: number) => {
return new Promise((resolve) => {
setTimeout(() => resolve(), seconds * 1000)
})
}
Hi Everyone,
After a few hours of frustration, I finally mannaged to get a basic sample of the WebSocket code working. As @jargote mentioned already, the connect() method of the websocket client actually does not return a promise. This means that the subscribe() method is immediately called after the connect when the connection has not been established yet.
After waiting for the connection to be established I ran into the second issue. The subscribeData object refers to the trading pair btc-usd. This is actually case sensitive and should be BTC-USD. Even the examples in the api documentaiton is lowercase and will not work.
Enough about the issues, more about the working code:
const Shrimpy = require('shrimpy-node');
let apiClient = null;
let wsClient = null;
let token = null;
const publicKey = "<Public Key Here>";
const privateKey = "<Private Key Here>";
function handler(msg){
console.log(msg);
};
function subscribeWhenConnected(oData){
if (wsClient.getReadyState() === 1) {
console.log("Subcribing to the order book for ETH-BTC");
wsClient.subscribe(oData, handler);
} else {
console.log("waiting for ws connection...");
setTimeout(subscribeWhenConnected.bind(null, oData), 1000);
}
};
function unsubscribe(oData){
console.log("Unsubcribing now");
wsClient.unsubscribe(oData);
console.log("Stopping the application");
process.exit(1);
};
(async () => {
apiClient = new Shrimpy.ShrimpyApiClient(publicKey, privateKey);
token = await apiClient.getToken();
wsClient = new Shrimpy.ShrimpyWsClient(function (error) {
console.error(error);
}, token);
wsClient.connect();
subscribeWhenConnected({
"type": "subscribe",
"pair": "ETH-BTC",
"exchange": "binance",
"channel": "orderbook"
});
setTimeout(unsubscribe.bind(null, {
"type": "unsubscribe",
"pair": "ETH-BTC",
"exchange": "binance",
"channel": "orderbook"
}), 10000);
})();
NOTES:
- We use the public and private key with the
ShrimpyApiClientto create a new instance of the API Client - We then use the ShrimpyApiClient to generate a valid token that will be used for the ShrimpyWsClient. VERY IMPORTANT: the
getToken()method returns a promise, so wait for it to finish. If you do not wait you will get an error that the token is invalid when trying to instantiate a new instance of the websocket client. - With a valid token we create a new instance of the
ShrimpyWsClientwith an inline error callback. - We then call the method
wsClient.connect(); - Now the important part. Knowing that the connection will not be established yet, we call the function
subscribeWhenConnectedwith the payload we would like to subscribe too. - We then set a timeout for 10 seconds where we will then unsubscribe and stop the application.
subscribeWhenConnected
This is a recursive function that will call itself every second to check if the connection state of the wsClient changed. Once the state is 1 the connection is ready and we can now successfully subscribe to the order book by calling the subscribe on the websocket client.
Hope this saves someone time in the future!