diff --git a/index.d.ts b/index.d.ts index fb5fe675..028d23a7 100644 --- a/index.d.ts +++ b/index.d.ts @@ -243,7 +243,6 @@ declare module 'gdax' { } interface WebsocketClientOptions { - heartbeat?: boolean; channels?: string[]; } @@ -252,7 +251,7 @@ declare module 'gdax' { productIds: string[], websocketURI?: string, auth?: {key:string, secret:string, passphrase:string}, - { heartbeat, channels }?: WebsocketClientOptions ); + { channels }?: WebsocketClientOptions ); on(event: 'message', eventHandler: (data:object) => void); on(event: 'error', eventHandler: (err) => void); diff --git a/lib/clients/websocket.js b/lib/clients/websocket.js index fa73490a..1af2e38f 100644 --- a/lib/clients/websocket.js +++ b/lib/clients/websocket.js @@ -14,20 +14,21 @@ class WebsocketClient extends EventEmitter { productIDs, websocketURI = 'wss://ws-feed.gdax.com', auth = null, - { heartbeat = false, channels = null } = {} + { channels = null } = {} ) { super(); this.productIDs = Utils.determineProductIDs(productIDs); this.websocketURI = websocketURI; - this.channels = channels; this.auth = Utils.checkAuth(auth); - this.heartbeat = heartbeat; + this.channels = channels || ['full']; + if (!this.channels.includes('heartbeat')) { + this.channels.push('heartbeat'); + } this.connect(); } connect() { if (this.socket) { - clearInterval(this.pinger); this.socket.close(); } @@ -40,8 +41,6 @@ class WebsocketClient extends EventEmitter { } disconnect() { - clearInterval(this.pinger); - if (!this.socket) { throw new Error('Could not disconnect (not connected)'); } @@ -55,12 +54,9 @@ class WebsocketClient extends EventEmitter { const subscribeMessage = { type: 'subscribe', product_ids: this.productIDs, + channels: this.channels, }; - if (this.channels) { - subscribeMessage.channels = this.channels; - } - // Add Signature if (this.auth.secret) { let sig = signRequest( @@ -72,26 +68,9 @@ class WebsocketClient extends EventEmitter { } this.socket.send(JSON.stringify(subscribeMessage)); - - if (this.heartbeat) { - // send heartbeat - const heartbeatMessage = { - type: 'heartbeat', - on: true, - }; - this.socket.send(JSON.stringify(heartbeatMessage)); - } else { - // Set a 30 second ping to keep connection alive - this.pinger = setInterval(() => { - if (this.socket) { - this.socket.ping('keepalive'); - } - }, 30000); - } } onClose() { - clearInterval(this.pinger); this.socket = null; this.emit('close'); } diff --git a/lib/orderbook_sync.js b/lib/orderbook_sync.js index 8a952f7f..3334dd7b 100644 --- a/lib/orderbook_sync.js +++ b/lib/orderbook_sync.js @@ -10,10 +10,9 @@ class OrderbookSync extends WebsocketClient { productIDs, apiURI = 'https://api.gdax.com', websocketURI = 'wss://ws-feed.gdax.com', - auth = null, - { heartbeat = false } = {} + auth = null ) { - super(productIDs, websocketURI, auth, { heartbeat }); + super(productIDs, websocketURI, auth); this.apiURI = apiURI; this.auth = Utils.checkAuth(auth); diff --git a/tests/websocket.spec.js b/tests/websocket.spec.js index b4c7613b..2464e120 100644 --- a/tests/websocket.spec.js +++ b/tests/websocket.spec.js @@ -18,17 +18,16 @@ suite('WebsocketClient', () => { }); }); - test('subscribes to the default product (BTC-USD) if undefined', done => { + test('subscribes to the default product (BTC-USD) and default channel (full) if undefined', done => { const server = testserver(++port, () => { new Gdax.WebsocketClient(null, 'ws://localhost:' + port); }); server.on('connection', socket => { socket.on('message', data => { const msg = JSON.parse(data); - assert.deepEqual(msg, { - type: 'subscribe', - product_ids: ['BTC-USD'], - }); + assert.equal(msg.type, 'subscribe'); + assert.deepEqual(msg.product_ids, ['BTC-USD']); + assert.deepEqual(msg.channels, ['full', 'heartbeat']); server.close(); done(); @@ -43,10 +42,8 @@ suite('WebsocketClient', () => { server.on('connection', socket => { socket.on('message', data => { const msg = JSON.parse(data); - assert.deepEqual(msg, { - type: 'subscribe', - product_ids: ['BTC-USD'], - }); + assert.equal(msg.type, 'subscribe'); + assert.deepEqual(msg.product_ids, ['BTC-USD']); server.close(); done(); @@ -61,10 +58,8 @@ suite('WebsocketClient', () => { server.on('connection', socket => { socket.on('message', data => { const msg = JSON.parse(data); - assert.deepEqual(msg, { - type: 'subscribe', - product_ids: ['BTC-USD'], - }); + assert.equal(msg.type, 'subscribe'); + assert.deepEqual(msg.product_ids, ['BTC-USD']); server.close(); done(); @@ -79,10 +74,8 @@ suite('WebsocketClient', () => { server.on('connection', socket => { socket.on('message', data => { const msg = JSON.parse(data); - assert.deepEqual(msg, { - type: 'subscribe', - product_ids: ['BTC-EUR'], - }); + assert.equal(msg.type, 'subscribe'); + assert.deepEqual(msg.product_ids, ['BTC-EUR']); server.close(); done(); @@ -97,10 +90,8 @@ suite('WebsocketClient', () => { server.on('connection', socket => { socket.on('message', data => { const msg = JSON.parse(data); - assert.deepEqual(msg, { - type: 'subscribe', - product_ids: ['ETH-USD'], - }); + assert.equal(msg.type, 'subscribe'); + assert.deepEqual(msg.product_ids, ['ETH-USD']); server.close(); done(); @@ -131,7 +122,7 @@ suite('WebsocketClient', () => { }); }); - test('passes channels through', done => { + test('passes channels through with heartbeat added', done => { const server = testserver(++port, () => { new Gdax.WebsocketClient( 'ETH-USD', @@ -150,7 +141,7 @@ suite('WebsocketClient', () => { assert.equal(msg.type, 'subscribe'); assert.equal(msg.key, 'suchkey'); assert.equal(msg.passphrase, 'muchpassphrase'); - assert.deepEqual(msg.channels, ['user', 'ticker']); + assert.deepEqual(msg.channels, ['user', 'ticker', 'heartbeat']); assert(msg.timestamp); assert(msg.signature); server.close(); @@ -159,70 +150,3 @@ suite('WebsocketClient', () => { }); }); }); - -test('passes heartbeat details through', done => { - let calls = 0; - const server = testserver(++port, () => { - new Gdax.WebsocketClient( - 'ETH-USD', - 'ws://localhost:' + port, - { - key: 'suchkey', - secret: 'suchsecret', - passphrase: 'muchpassphrase', - }, - { heartbeat: true } - ); - }); - server.on('connection', socket => { - socket.on('message', data => { - const msg = JSON.parse(data); - calls++; - - if (msg.type === 'subscribe') { - assert.equal(msg.key, 'suchkey'); - assert.equal(msg.passphrase, 'muchpassphrase'); - assert(msg.timestamp); - assert(msg.signature); - } else { - assert.equal(msg.type, 'heartbeat'); - assert.equal(msg.on, true); - } - - if (calls > 1) { - server.close(); - done(); - } - }); - }); -}); - -test('passes heartbeat details through without authentication details', done => { - let calls = 0; - const server = testserver(++port, () => { - new Gdax.WebsocketClient( - ['BTC-USD', 'ETH-USD'], - 'ws://localhost:' + port, - null, - { heartbeat: true } - ); - }); - server.on('connection', socket => { - socket.on('message', data => { - const msg = JSON.parse(data); - calls++; - - if (msg.type === 'subscribe') { - assert.deepEqual(msg.product_ids, ['BTC-USD', 'ETH-USD']); - } else { - assert.equal(msg.type, 'heartbeat'); - assert.equal(msg.on, true); - } - - if (calls > 1) { - server.close(); - done(); - } - }); - }); -});