binance 2.1.6 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/main-client.d.ts +31 -1
- package/lib/main-client.js +48 -0
- package/lib/main-client.js.map +1 -1
- package/lib/types/shared.d.ts +1 -1
- package/lib/types/spot.d.ts +74 -3
- package/lib/util/BaseRestClient.js +3 -1
- package/lib/util/BaseRestClient.js.map +1 -1
- package/lib/util/WsStore.d.ts +43 -21
- package/lib/util/WsStore.js +15 -6
- package/lib/util/WsStore.js.map +1 -1
- package/lib/util/beautifier.js +32 -33
- package/lib/util/beautifier.js.map +1 -1
- package/lib/websocket-client.d.ts +7 -14
- package/lib/websocket-client.js +115 -159
- package/lib/websocket-client.js.map +1 -1
- package/package.json +1 -1
package/lib/websocket-client.js
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
2
21
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
22
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
23
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -12,7 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
31
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
32
|
};
|
|
14
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.WebsocketClient = exports.parseRawWsMessage =
|
|
34
|
+
exports.WebsocketClient = exports.parseRawWsMessage = void 0;
|
|
16
35
|
const events_1 = require("events");
|
|
17
36
|
const isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
|
|
18
37
|
const logger_1 = require("./logger");
|
|
@@ -21,7 +40,7 @@ const usdm_client_1 = require("./usdm-client");
|
|
|
21
40
|
const beautifier_1 = __importDefault(require("./util/beautifier"));
|
|
22
41
|
const requestUtils_1 = require("./util/requestUtils");
|
|
23
42
|
const ws_utils_1 = require("./util/ws-utils");
|
|
24
|
-
const WsStore_1 =
|
|
43
|
+
const WsStore_1 = __importStar(require("./util/WsStore"));
|
|
25
44
|
const coinm_client_1 = require("./coinm-client");
|
|
26
45
|
const wsBaseEndpoints = {
|
|
27
46
|
spot: 'wss://stream.binance.com:9443',
|
|
@@ -32,22 +51,9 @@ const wsBaseEndpoints = {
|
|
|
32
51
|
coinm: 'wss://dstream.binance.com',
|
|
33
52
|
coinmTestnet: 'wss://dstream.binancefuture.com',
|
|
34
53
|
options: 'wss://vstream.binance.com',
|
|
35
|
-
optionsTestnet: 'wss://testnetws.binanceops.com'
|
|
54
|
+
optionsTestnet: 'wss://testnetws.binanceops.com',
|
|
36
55
|
};
|
|
37
56
|
const loggerCategory = { category: 'binance-ws' };
|
|
38
|
-
const READY_STATE_INITIAL = 0;
|
|
39
|
-
const READY_STATE_CONNECTING = 1;
|
|
40
|
-
const READY_STATE_CONNECTED = 2;
|
|
41
|
-
const READY_STATE_CLOSING = 3;
|
|
42
|
-
const READY_STATE_RECONNECTING = 4;
|
|
43
|
-
var WsConnectionState;
|
|
44
|
-
(function (WsConnectionState) {
|
|
45
|
-
WsConnectionState[WsConnectionState["READY_STATE_INITIAL"] = 0] = "READY_STATE_INITIAL";
|
|
46
|
-
WsConnectionState[WsConnectionState["READY_STATE_CONNECTING"] = 1] = "READY_STATE_CONNECTING";
|
|
47
|
-
WsConnectionState[WsConnectionState["READY_STATE_CONNECTED"] = 2] = "READY_STATE_CONNECTED";
|
|
48
|
-
WsConnectionState[WsConnectionState["READY_STATE_CLOSING"] = 3] = "READY_STATE_CLOSING";
|
|
49
|
-
WsConnectionState[WsConnectionState["READY_STATE_RECONNECTING"] = 4] = "READY_STATE_RECONNECTING";
|
|
50
|
-
})(WsConnectionState = exports.WsConnectionState || (exports.WsConnectionState = {}));
|
|
51
57
|
function throwUnhandledSwitch(x, msg) {
|
|
52
58
|
throw new Error(msg);
|
|
53
59
|
}
|
|
@@ -90,6 +96,8 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
90
96
|
this.options = Object.assign({ pongTimeout: 7500, pingInterval: 10000, reconnectTimeout: 500 }, options);
|
|
91
97
|
this.listenKeyStateStore = {};
|
|
92
98
|
this.wsUrlKeyMap = {};
|
|
99
|
+
// add default error handling so this doesn't crash node (if the user didn't set a handler)
|
|
100
|
+
this.on('error', () => { });
|
|
93
101
|
}
|
|
94
102
|
getRestClientOptions() {
|
|
95
103
|
return Object.assign(Object.assign(Object.assign({}, this.options), this.options.restOptions), { api_key: this.options.api_key, api_secret: this.options.api_secret });
|
|
@@ -107,13 +115,9 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
107
115
|
if (typeof ws.on === 'function') {
|
|
108
116
|
ws.on('ping', (event) => this.onWsPing(event, wsRefKey, ws, 'event'));
|
|
109
117
|
ws.on('pong', (event) => this.onWsPong(event, wsRefKey, 'event'));
|
|
110
|
-
// ws.on('message', event => this.onWsMessage(event, wsRefKey, 'event'));
|
|
111
|
-
// ws.on('close', event => this.onWsClose(event, wsRefKey, ws, url));
|
|
112
|
-
// ws.on('error', event => this.onWsError(event, wsRefKey, ws));
|
|
113
|
-
// ws.on('open', event => this.onWsOpen(event, wsRefKey));
|
|
114
118
|
}
|
|
115
119
|
ws.onopen = (event) => this.onWsOpen(event, wsRefKey, url);
|
|
116
|
-
ws.onerror = (event) => this.
|
|
120
|
+
ws.onerror = (event) => this.parseWsError('WS Error Event', event, wsRefKey, url);
|
|
117
121
|
ws.onclose = (event) => this.onWsClose(event, wsRefKey, ws, url);
|
|
118
122
|
ws.onmessage = (event) => this.onWsMessage(event, wsRefKey, 'function');
|
|
119
123
|
// Not sure these work in the browser, the traditional event listeners are required for ping/pong frames in node
|
|
@@ -161,7 +165,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
161
165
|
}
|
|
162
166
|
onWsOpen(ws, wsKey, wsUrl) {
|
|
163
167
|
this.logger.silly(`onWsOpen(): ${wsUrl} : ${wsKey}`);
|
|
164
|
-
if (this.wsStore.isConnectionState(wsKey,
|
|
168
|
+
if (this.wsStore.isConnectionState(wsKey, WsStore_1.WsConnectionStateEnum.RECONNECTING)) {
|
|
165
169
|
this.logger.info('Websocket reconnected', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
|
|
166
170
|
this.emit('reconnected', { wsKey, ws });
|
|
167
171
|
}
|
|
@@ -169,7 +173,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
169
173
|
this.logger.info('Websocket connected', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
|
|
170
174
|
this.emit('open', { wsKey, ws });
|
|
171
175
|
}
|
|
172
|
-
this.setWsState(wsKey,
|
|
176
|
+
this.setWsState(wsKey, WsStore_1.WsConnectionStateEnum.CONNECTED);
|
|
173
177
|
const topics = [...this.wsStore.getTopics(wsKey)];
|
|
174
178
|
if (topics.length) {
|
|
175
179
|
this.requestSubscribeTopics(wsKey, topics);
|
|
@@ -179,14 +183,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
179
183
|
if (wsState.activePingTimer) {
|
|
180
184
|
clearInterval(wsState.activePingTimer);
|
|
181
185
|
}
|
|
182
|
-
wsState.activePingTimer = setInterval(() => this.sendPing(wsKey), this.options.pingInterval);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
onWsError(error, wsKey, ws) {
|
|
186
|
-
this.logger.error('Websocket error', Object.assign(Object.assign({}, loggerCategory), { wsKey, error }));
|
|
187
|
-
this.parseWsError('Websocket error', error, wsKey);
|
|
188
|
-
if (this.wsStore.isConnectionState(wsKey, READY_STATE_CONNECTED)) {
|
|
189
|
-
this.emit('error', { error, wsKey, ws });
|
|
186
|
+
wsState.activePingTimer = setInterval(() => this.sendPing(wsKey, wsUrl), this.options.pingInterval);
|
|
190
187
|
}
|
|
191
188
|
}
|
|
192
189
|
onWsClose(event, wsKey, ws, wsUrl) {
|
|
@@ -199,12 +196,12 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
199
196
|
if (isUserData) {
|
|
200
197
|
this.wsStore.delete(wsKey);
|
|
201
198
|
}
|
|
202
|
-
if (wsConnectionState !==
|
|
199
|
+
if (wsConnectionState !== WsStore_1.WsConnectionStateEnum.CLOSING) {
|
|
203
200
|
this.reconnectWithDelay(wsKey, this.options.reconnectTimeout, wsUrl);
|
|
204
201
|
this.emit('reconnecting', { wsKey, event, ws });
|
|
205
202
|
}
|
|
206
203
|
else {
|
|
207
|
-
this.setWsState(wsKey,
|
|
204
|
+
this.setWsState(wsKey, WsStore_1.WsConnectionStateEnum.INITIAL);
|
|
208
205
|
this.emit('close', { wsKey, event, ws });
|
|
209
206
|
}
|
|
210
207
|
}
|
|
@@ -240,7 +237,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
240
237
|
'ORDER_TRADE_UPDATE',
|
|
241
238
|
'ACCOUNT_UPDATE',
|
|
242
239
|
'ORDER_TRADE_UPDATE',
|
|
243
|
-
'ACCOUNT_CONFIG_UPDATE'
|
|
240
|
+
'ACCOUNT_CONFIG_UPDATE',
|
|
244
241
|
].includes(eventType)) {
|
|
245
242
|
this.emit('formattedUserDataMessage', beautifiedMessage);
|
|
246
243
|
}
|
|
@@ -252,7 +249,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
252
249
|
this.emit('reply', {
|
|
253
250
|
type: event.type,
|
|
254
251
|
data: msg,
|
|
255
|
-
wsKey
|
|
252
|
+
wsKey,
|
|
256
253
|
});
|
|
257
254
|
return;
|
|
258
255
|
}
|
|
@@ -264,14 +261,11 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
264
261
|
this.emit('error', { wsKey, error: e, rawEvent: event, source });
|
|
265
262
|
}
|
|
266
263
|
}
|
|
267
|
-
sendPing(wsKey) {
|
|
264
|
+
sendPing(wsKey, wsUrl) {
|
|
268
265
|
this.clearPongTimer(wsKey);
|
|
269
266
|
this.logger.silly('Sending ping', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
|
|
270
267
|
this.tryWsPing(wsKey);
|
|
271
|
-
this.wsStore.get(wsKey, true).activePongTimer = setTimeout(() =>
|
|
272
|
-
this.logger.info('Pong timeout - closing socket to reconnect', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
|
|
273
|
-
this.close(wsKey, true);
|
|
274
|
-
}, this.options.pongTimeout);
|
|
268
|
+
this.wsStore.get(wsKey, true).activePongTimer = setTimeout(() => this.executeReconnectableClose(wsKey, 'Pong timeout', wsUrl), this.options.pongTimeout);
|
|
275
269
|
}
|
|
276
270
|
onWsPing(event, wsKey, ws, source) {
|
|
277
271
|
this.logger.silly('Received ping, sending pong frame', Object.assign(Object.assign({}, loggerCategory), { wsKey,
|
|
@@ -285,14 +279,41 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
285
279
|
source }));
|
|
286
280
|
this.clearPongTimer(wsKey);
|
|
287
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* Closes a connection, if it's even open. If open, this will trigger a reconnect asynchronously.
|
|
284
|
+
* If closed, trigger a reconnect immediately
|
|
285
|
+
*/
|
|
286
|
+
executeReconnectableClose(wsKey, reason, wsUrl) {
|
|
287
|
+
this.logger.info(`${reason} - closing socket to reconnect`, Object.assign(Object.assign({}, loggerCategory), { wsKey,
|
|
288
|
+
reason }));
|
|
289
|
+
const wasOpen = this.wsStore.isWsOpen(wsKey);
|
|
290
|
+
ws_utils_1.terminateWs(this.getWs(wsKey));
|
|
291
|
+
delete this.wsStore.get(wsKey, true).activePongTimer;
|
|
292
|
+
this.clearPingTimer(wsKey);
|
|
293
|
+
this.clearPongTimer(wsKey);
|
|
294
|
+
if (!wasOpen) {
|
|
295
|
+
this.logger.info(`${reason} - socket already closed - trigger immediate reconnect`, Object.assign(Object.assign({}, loggerCategory), { wsKey,
|
|
296
|
+
reason }));
|
|
297
|
+
this.reconnectWithDelay(wsKey, this.options.reconnectTimeout, wsUrl);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
288
300
|
close(wsKey, willReconnect) {
|
|
289
301
|
var _a;
|
|
290
302
|
this.logger.info('Closing connection', Object.assign(Object.assign({}, loggerCategory), { wsKey }));
|
|
291
|
-
this.setWsState(wsKey, willReconnect
|
|
303
|
+
this.setWsState(wsKey, willReconnect
|
|
304
|
+
? WsStore_1.WsConnectionStateEnum.RECONNECTING
|
|
305
|
+
: WsStore_1.WsConnectionStateEnum.CLOSING);
|
|
292
306
|
this.clearTimers(wsKey);
|
|
293
307
|
(_a = this.getWs(wsKey)) === null || _a === void 0 ? void 0 : _a.close();
|
|
294
308
|
ws_utils_1.terminateWs(this.getWs(wsKey));
|
|
295
309
|
}
|
|
310
|
+
closeAll(force) {
|
|
311
|
+
const keys = this.wsStore.getKeys();
|
|
312
|
+
this.logger.info(`Closing all ws connections: ${keys}`);
|
|
313
|
+
keys.forEach((key) => {
|
|
314
|
+
this.close(key, force);
|
|
315
|
+
});
|
|
316
|
+
}
|
|
296
317
|
closeWs(ws, willReconnect) {
|
|
297
318
|
const wsKey = this.wsUrlKeyMap[ws.url];
|
|
298
319
|
if (!wsKey) {
|
|
@@ -300,9 +321,11 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
300
321
|
}
|
|
301
322
|
return this.close(wsKey, willReconnect);
|
|
302
323
|
}
|
|
303
|
-
parseWsError(context, error, wsKey) {
|
|
324
|
+
parseWsError(context, error, wsKey, wsUrl) {
|
|
325
|
+
this.logger.error(context, Object.assign(Object.assign({}, loggerCategory), { wsKey, error }));
|
|
304
326
|
if (!error.message) {
|
|
305
327
|
this.logger.error(`${context} due to unexpected error: `, error);
|
|
328
|
+
this.emit('error', { error, wsKey, wsUrl });
|
|
306
329
|
return;
|
|
307
330
|
}
|
|
308
331
|
switch (error.message) {
|
|
@@ -310,18 +333,32 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
310
333
|
this.logger.error(`${context} due to 401 authorization failure.`, Object.assign(Object.assign({}, loggerCategory), { wsKey }));
|
|
311
334
|
break;
|
|
312
335
|
default:
|
|
313
|
-
this.
|
|
336
|
+
if (this.wsStore.getConnectionState(wsKey) !==
|
|
337
|
+
WsStore_1.WsConnectionStateEnum.CLOSING) {
|
|
338
|
+
this.logger.error(`${context} due to unexpected response error: "${(error === null || error === void 0 ? void 0 : error.msg) || (error === null || error === void 0 ? void 0 : error.message) || error}"`, Object.assign(Object.assign({}, loggerCategory), { wsKey, error }));
|
|
339
|
+
this.executeReconnectableClose(wsKey, 'unhandled onWsError', wsUrl);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
this.logger.info(`${wsKey} socket forcefully closed. Will not reconnect.`);
|
|
343
|
+
}
|
|
314
344
|
break;
|
|
315
345
|
}
|
|
346
|
+
this.emit('error', { error, wsKey, wsUrl });
|
|
316
347
|
}
|
|
317
348
|
reconnectWithDelay(wsKey, connectionDelayMs, wsUrl) {
|
|
349
|
+
var _a;
|
|
318
350
|
this.clearTimers(wsKey);
|
|
319
|
-
if (this.wsStore.getConnectionState(wsKey) !==
|
|
320
|
-
|
|
351
|
+
if (this.wsStore.getConnectionState(wsKey) !==
|
|
352
|
+
WsStore_1.WsConnectionStateEnum.CONNECTING) {
|
|
353
|
+
this.setWsState(wsKey, WsStore_1.WsConnectionStateEnum.RECONNECTING);
|
|
321
354
|
}
|
|
322
355
|
this.logger.info('Reconnecting to websocket with delay...', Object.assign(Object.assign({}, loggerCategory), { wsKey,
|
|
323
356
|
connectionDelayMs }));
|
|
324
|
-
|
|
357
|
+
if ((_a = this.wsStore.get(wsKey)) === null || _a === void 0 ? void 0 : _a.activeReconnectTimer) {
|
|
358
|
+
this.clearReconnectTimer(wsKey);
|
|
359
|
+
}
|
|
360
|
+
this.wsStore.get(wsKey, true).activeReconnectTimer = setTimeout(() => {
|
|
361
|
+
this.clearReconnectTimer(wsKey);
|
|
325
362
|
if (wsKey.includes('userData')) {
|
|
326
363
|
const { market, symbol, isTestnet } = requestUtils_1.getContextFromWsKey(wsKey);
|
|
327
364
|
this.logger.info('Reconnecting to user data stream', Object.assign(Object.assign({}, loggerCategory), { wsKey,
|
|
@@ -340,6 +377,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
340
377
|
clearTimers(wsKey) {
|
|
341
378
|
this.clearPingTimer(wsKey);
|
|
342
379
|
this.clearPongTimer(wsKey);
|
|
380
|
+
this.clearReconnectTimer(wsKey);
|
|
343
381
|
}
|
|
344
382
|
// Send a ping at intervals
|
|
345
383
|
clearPingTimer(wsKey) {
|
|
@@ -359,112 +397,20 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
359
397
|
wsState.activePongTimer = undefined;
|
|
360
398
|
}
|
|
361
399
|
}
|
|
400
|
+
// Timer tracking that a reconnect is about to happen / in progress
|
|
401
|
+
clearReconnectTimer(wsKey) {
|
|
402
|
+
const wsState = this.wsStore.get(wsKey);
|
|
403
|
+
if (wsState === null || wsState === void 0 ? void 0 : wsState.activeReconnectTimer) {
|
|
404
|
+
clearTimeout(wsState.activeReconnectTimer);
|
|
405
|
+
wsState.activeReconnectTimer = undefined;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
362
408
|
getWsBaseUrl(market, wsKey) {
|
|
363
409
|
if (this.options.wsUrl) {
|
|
364
410
|
return this.options.wsUrl;
|
|
365
411
|
}
|
|
366
412
|
return wsBaseEndpoints[market];
|
|
367
413
|
}
|
|
368
|
-
// // const networkKey = this.options.livenet ? 'livenet' : 'testnet';
|
|
369
|
-
// // if (this.isLinear() || wsKey.startsWith('linear')){
|
|
370
|
-
// // if (wsKey === wsKeyLinearPublic) {
|
|
371
|
-
// // return linearEndpoints.public[networkKey];
|
|
372
|
-
// // }
|
|
373
|
-
// // if (wsKey === wsKeyLinearPrivate) {
|
|
374
|
-
// // return linearEndpoints.private[networkKey];
|
|
375
|
-
// // }
|
|
376
|
-
// // this.logger.error('Unhandled linear wsKey: ', { ...loggerCategory, wsKey });
|
|
377
|
-
// // return linearEndpoints[networkKey];
|
|
378
|
-
// // }
|
|
379
|
-
// // return inverseEndpoints[networkKey];
|
|
380
|
-
// }
|
|
381
|
-
// private getWsKeyForTopic(baseUrlKey: BinanceBaseUrlKey, topic: string) {
|
|
382
|
-
// return isSpotBase(baseUrlKey) ? wsKeySpot : getLinearWsKeyForTopic(topic);
|
|
383
|
-
// }
|
|
384
|
-
// public subscribeSpotPublic(wsTopics: string[] | string) {
|
|
385
|
-
// return this.subscribe('spot', wsTopics);
|
|
386
|
-
// }
|
|
387
|
-
// public unsubscribeSpotPublic(wsTopics: string[] | string) {
|
|
388
|
-
// return this.unsubscribe('spot', wsTopics);
|
|
389
|
-
// }
|
|
390
|
-
// TODO: force these through single stream, instead of general one
|
|
391
|
-
/**
|
|
392
|
-
* Add topic/topics to WS subscription list
|
|
393
|
-
*/
|
|
394
|
-
// public subscribe(baseUrlKey: BinanceBaseUrlKey, wsTopics: string[] | string) {
|
|
395
|
-
// const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
|
|
396
|
-
// topics.forEach(topic => this.wsStore.addTopic(
|
|
397
|
-
// this.getWsKeyForTopic(baseUrlKey, topic),//wsKeySpot
|
|
398
|
-
// topic
|
|
399
|
-
// ));
|
|
400
|
-
// // attempt to send subscription topic per websocket
|
|
401
|
-
// this.wsStore.getKeys().forEach((wsKey: WsKey) => {
|
|
402
|
-
// // if connected, send subscription request
|
|
403
|
-
// if (this.wsStore.isConnectionState(wsKey, READY_STATE_CONNECTED)) {
|
|
404
|
-
// return this.requestSubscribeTopics(wsKey, topics);
|
|
405
|
-
// }
|
|
406
|
-
// // start connection process if it hasn't yet begun. Topics are automatically subscribed to on-connect
|
|
407
|
-
// if (
|
|
408
|
-
// !this.wsStore.isConnectionState(wsKey, READY_STATE_CONNECTING) &&
|
|
409
|
-
// !this.wsStore.isConnectionState(wsKey, READY_STATE_RECONNECTING)
|
|
410
|
-
// ) {
|
|
411
|
-
// return this.connectSingleStream(wsKey);
|
|
412
|
-
// }
|
|
413
|
-
// });
|
|
414
|
-
// }
|
|
415
|
-
/**
|
|
416
|
-
* Remove topic/topics from WS subscription list
|
|
417
|
-
*/
|
|
418
|
-
// public unsubscribe(baseUrlKey: BinanceBaseUrlKey, wsTopics: string[] | string) {
|
|
419
|
-
// const topics = Array.isArray(wsTopics) ? wsTopics : [wsTopics];
|
|
420
|
-
// topics.forEach(topic => this.wsStore.deleteTopic(
|
|
421
|
-
// this.getWsKeyForTopic(baseUrlKey, topic),
|
|
422
|
-
// topic
|
|
423
|
-
// ));
|
|
424
|
-
// this.wsStore.getKeys().forEach((wsKey: WsKey) => {
|
|
425
|
-
// // unsubscribe request only necessary if active connection exists
|
|
426
|
-
// if (this.wsStore.isConnectionState(wsKey, READY_STATE_CONNECTED)) {
|
|
427
|
-
// this.requestUnsubscribeTopics(wsKey, topics);
|
|
428
|
-
// }
|
|
429
|
-
// });
|
|
430
|
-
// }
|
|
431
|
-
// /**
|
|
432
|
-
// * Request connection of all dependent websockets, instead of waiting for automatic connection by library
|
|
433
|
-
// */
|
|
434
|
-
// public connectAll(): Promise<WebSocket | undefined>[] | undefined {
|
|
435
|
-
// return [this.connectSingleStream(wsKeySpot)];
|
|
436
|
-
// // if (this.isInverse()) {
|
|
437
|
-
// // return [this.connect(wsKeySpot)];
|
|
438
|
-
// // }
|
|
439
|
-
// // if (this.isLinear()) {
|
|
440
|
-
// // return [this.connect(wsKeyLinearPublic), this.connect(wsKeyLinearPrivate)];
|
|
441
|
-
// // }
|
|
442
|
-
// }
|
|
443
|
-
// private async connectSingleStream(streamName: string): Promise<WebSocket | undefined> {
|
|
444
|
-
// try {
|
|
445
|
-
// if (this.wsStore.isWsOpen(streamName)) {
|
|
446
|
-
// this.logger.error('Refused to connect to ws with existing active connection', { ...loggerCategory, wsKey: streamName })
|
|
447
|
-
// return this.wsStore.getWs(streamName);
|
|
448
|
-
// }
|
|
449
|
-
// if (this.wsStore.isConnectionState(streamName, READY_STATE_CONNECTING)) {
|
|
450
|
-
// this.logger.error('Refused to connect to ws, connection attempt already active', { ...loggerCategory, wsKey: streamName })
|
|
451
|
-
// return;
|
|
452
|
-
// }
|
|
453
|
-
// if (
|
|
454
|
-
// !this.wsStore.getConnectionState(streamName) ||
|
|
455
|
-
// this.wsStore.isConnectionState(streamName, READY_STATE_INITIAL)
|
|
456
|
-
// ) {
|
|
457
|
-
// this.setWsState(streamName, READY_STATE_CONNECTING);
|
|
458
|
-
// }
|
|
459
|
-
// const url = this.getWsUrl(streamName) + '/stream?';
|
|
460
|
-
// //+ authParams;
|
|
461
|
-
// const ws = this.connectToWsUrl(url, streamName);
|
|
462
|
-
// return this.wsStore.setWs(streamName, ws);
|
|
463
|
-
// } catch (err) {
|
|
464
|
-
// this.parseWsError('Connection failed', err, streamName);
|
|
465
|
-
// this.reconnectWithDelay(streamName, this.options.reconnectTimeout!);
|
|
466
|
-
// }
|
|
467
|
-
// }
|
|
468
414
|
getWs(wsKey) {
|
|
469
415
|
return this.wsStore.getWs(wsKey);
|
|
470
416
|
}
|
|
@@ -508,7 +454,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
508
454
|
const wsMessage = JSON.stringify({
|
|
509
455
|
method: 'SUBSCRIBE',
|
|
510
456
|
params: topics,
|
|
511
|
-
id: new Date().getTime()
|
|
457
|
+
id: new Date().getTime(),
|
|
512
458
|
});
|
|
513
459
|
this.tryWsSend(wsKey, wsMessage);
|
|
514
460
|
}
|
|
@@ -519,7 +465,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
519
465
|
const wsMessage = JSON.stringify({
|
|
520
466
|
op: 'UNSUBSCRIBE',
|
|
521
467
|
params: topics,
|
|
522
|
-
id: new Date().getTime()
|
|
468
|
+
id: new Date().getTime(),
|
|
523
469
|
});
|
|
524
470
|
this.tryWsSend(wsKey, wsMessage);
|
|
525
471
|
}
|
|
@@ -529,7 +475,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
529
475
|
requestListSubscriptions(wsKey, requestId) {
|
|
530
476
|
const wsMessage = JSON.stringify({
|
|
531
477
|
method: 'LIST_SUBSCRIPTIONS',
|
|
532
|
-
id: requestId
|
|
478
|
+
id: requestId,
|
|
533
479
|
});
|
|
534
480
|
this.tryWsSend(wsKey, wsMessage);
|
|
535
481
|
}
|
|
@@ -540,7 +486,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
540
486
|
const wsMessage = JSON.stringify({
|
|
541
487
|
method: 'SET_PROPERTY',
|
|
542
488
|
params: [property, value],
|
|
543
|
-
id: requestId
|
|
489
|
+
id: requestId,
|
|
544
490
|
});
|
|
545
491
|
this.tryWsSend(wsKey, wsMessage);
|
|
546
492
|
}
|
|
@@ -551,7 +497,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
551
497
|
const wsMessage = JSON.stringify({
|
|
552
498
|
method: 'GET_PROPERTY',
|
|
553
499
|
params: [property],
|
|
554
|
-
id: requestId
|
|
500
|
+
id: requestId,
|
|
555
501
|
});
|
|
556
502
|
this.tryWsSend(wsKey, wsMessage);
|
|
557
503
|
}
|
|
@@ -569,7 +515,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
569
515
|
market,
|
|
570
516
|
lastKeepAlive: 0,
|
|
571
517
|
keepAliveTimer: undefined,
|
|
572
|
-
keepAliveFailures: 0
|
|
518
|
+
keepAliveFailures: 0,
|
|
573
519
|
};
|
|
574
520
|
return this.listenKeyStateStore[listenKey];
|
|
575
521
|
}
|
|
@@ -949,7 +895,9 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
949
895
|
this.logger.silly('Existing spot user data connection in progress for listen key. Avoiding duplicate');
|
|
950
896
|
return this.getWs(wsKey);
|
|
951
897
|
}
|
|
952
|
-
this.setWsState(wsKey, isReconnecting
|
|
898
|
+
this.setWsState(wsKey, isReconnecting
|
|
899
|
+
? WsStore_1.WsConnectionStateEnum.RECONNECTING
|
|
900
|
+
: WsStore_1.WsConnectionStateEnum.CONNECTING);
|
|
953
901
|
const ws = this.connectToWsUrl(this.getWsBaseUrl(market, wsKey) + `/ws/${listenKey}`, wsKey, forceNewConnection);
|
|
954
902
|
// Start & store timer to keep alive listen key (and handle expiration)
|
|
955
903
|
this.setKeepAliveListenKeyTimer(listenKey, market, ws, wsKey);
|
|
@@ -983,7 +931,9 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
983
931
|
this.logger.silly('Existing margin user data connection in progress for listen key. Avoiding duplicate');
|
|
984
932
|
return this.getWs(wsKey);
|
|
985
933
|
}
|
|
986
|
-
this.setWsState(wsKey, isReconnecting
|
|
934
|
+
this.setWsState(wsKey, isReconnecting
|
|
935
|
+
? WsStore_1.WsConnectionStateEnum.RECONNECTING
|
|
936
|
+
: WsStore_1.WsConnectionStateEnum.CONNECTING);
|
|
987
937
|
const ws = this.connectToWsUrl(this.getWsBaseUrl(market, wsKey) + `/ws/${listenKey}`, wsKey, forceNewConnection);
|
|
988
938
|
// Start & store timer to keep alive listen key (and handle expiration)
|
|
989
939
|
this.setKeepAliveListenKeyTimer(listenKey, market, ws, wsKey);
|
|
@@ -1003,7 +953,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
1003
953
|
try {
|
|
1004
954
|
const lowerCaseSymbol = symbol.toLowerCase();
|
|
1005
955
|
const { listenKey } = yield this.getSpotRestClient().getIsolatedMarginUserDataListenKey({
|
|
1006
|
-
symbol: lowerCaseSymbol
|
|
956
|
+
symbol: lowerCaseSymbol,
|
|
1007
957
|
});
|
|
1008
958
|
const market = 'isolatedMargin';
|
|
1009
959
|
const wsKey = requestUtils_1.getWsKeyWithContext(market, 'userData', lowerCaseSymbol, listenKey);
|
|
@@ -1011,7 +961,9 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
1011
961
|
this.logger.silly('Existing isolated margin user data connection in progress for listen key. Avoiding duplicate');
|
|
1012
962
|
return this.getWs(wsKey);
|
|
1013
963
|
}
|
|
1014
|
-
this.setWsState(wsKey, isReconnecting
|
|
964
|
+
this.setWsState(wsKey, isReconnecting
|
|
965
|
+
? WsStore_1.WsConnectionStateEnum.RECONNECTING
|
|
966
|
+
: WsStore_1.WsConnectionStateEnum.CONNECTING);
|
|
1015
967
|
const ws = this.connectToWsUrl(this.getWsBaseUrl(market, wsKey) + `/ws/${listenKey}`, wsKey, forceNewConnection);
|
|
1016
968
|
// Start & store timer to keep alive listen key (and handle expiration)
|
|
1017
969
|
this.setKeepAliveListenKeyTimer(listenKey, market, ws, wsKey, symbol);
|
|
@@ -1021,7 +973,7 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
1021
973
|
this.logger.error(`Failed to connect to isolated margin user data`, Object.assign(Object.assign({}, loggerCategory), { error: e, symbol }));
|
|
1022
974
|
this.emit('error', {
|
|
1023
975
|
wsKey: 'isolatedMargin' + '_' + 'userData',
|
|
1024
|
-
error: e
|
|
976
|
+
error: e,
|
|
1025
977
|
});
|
|
1026
978
|
}
|
|
1027
979
|
});
|
|
@@ -1047,7 +999,9 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
1047
999
|
return this.getWs(wsKey);
|
|
1048
1000
|
}
|
|
1049
1001
|
// Necessary so client knows this is a reconnect
|
|
1050
|
-
this.setWsState(wsKey, isReconnecting
|
|
1002
|
+
this.setWsState(wsKey, isReconnecting
|
|
1003
|
+
? WsStore_1.WsConnectionStateEnum.RECONNECTING
|
|
1004
|
+
: WsStore_1.WsConnectionStateEnum.CONNECTING);
|
|
1051
1005
|
const ws = this.connectToWsUrl(this.getWsBaseUrl(market, wsKey) + `/ws/${listenKey}`, wsKey, forceNewConnection);
|
|
1052
1006
|
// Start & store timer to keep alive listen key (and handle expiration)
|
|
1053
1007
|
this.setKeepAliveListenKeyTimer(listenKey, market, ws, wsKey, undefined, isTestnet);
|
|
@@ -1074,7 +1028,9 @@ class WebsocketClient extends events_1.EventEmitter {
|
|
|
1074
1028
|
return this.getWs(wsKey);
|
|
1075
1029
|
}
|
|
1076
1030
|
// Necessary so client knows this is a reconnect
|
|
1077
|
-
this.setWsState(wsKey, isReconnecting
|
|
1031
|
+
this.setWsState(wsKey, isReconnecting
|
|
1032
|
+
? WsStore_1.WsConnectionStateEnum.RECONNECTING
|
|
1033
|
+
: WsStore_1.WsConnectionStateEnum.CONNECTING);
|
|
1078
1034
|
const ws = this.connectToWsUrl(this.getWsBaseUrl(market, wsKey) + `/ws/${listenKey}`, wsKey, forceNewConnection);
|
|
1079
1035
|
// Start & store timer to keep alive listen key (and handle expiration)
|
|
1080
1036
|
this.setKeepAliveListenKeyTimer(listenKey, market, ws, wsKey, undefined, isTestnet);
|