@fraserdarwent/xapi-node
Version:
This project is made possible to get data from Forex market, execute market or limit order with NodeJS/JS through WebSocket connection
125 lines • 5.19 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamConnection = void 0;
const __1 = require("../..");
const WebSocketWrapper_1 = require("../../modules/WebSocketWrapper");
const Log_1 = require("../../utils/Log");
const Enum_1 = require("../../enum/Enum");
const Queue_1 = require("../Queue");
class StreamConnection extends Queue_1.Queue {
constructor(XAPI, url) {
super(XAPI.rateLimit, Enum_1.TransactionType.STREAM);
this.session = '';
this.pingTimeout = new __1.Timer();
this.XAPI = XAPI;
this.WebSocket = new WebSocketWrapper_1.WebSocketWrapper(url);
this.WebSocket.onOpen(() => this.setConnectionStatus(Enum_1.ConnectionStatus.CONNECTING));
this.WebSocket.onClose(() => this.setConnectionStatus(Enum_1.ConnectionStatus.DISCONNECTED));
this.WebSocket.onMessage((json) => {
this.lastReceivedMessage = new __1.Time();
try {
const message = JSON.parse(json.toString().trim());
try {
this.callListener('command_' + message.command, [message.data, new __1.Time()]);
}
catch (e) {
const { name, message, stack } = new Error(e);
Log_1.Log.error('Stream WebSocket Handle Message ERROR');
Log_1.Log.hidden(name + '\n' + message + (stack ? '\n' + stack : ''), 'ERROR');
}
}
catch (e) {
const { name, message, stack } = new Error(e);
Log_1.Log.error('Stream WebSocket JSON parse ERROR');
Log_1.Log.hidden(name + '\n' + message + (stack ? '\n' + stack : '') + '\n\n' + json, 'ERROR');
}
});
this.WebSocket.onError((error) => {
const { name, message, stack } = new Error(error);
Log_1.Log.error('Stream WebSocket ERROR');
Log_1.Log.hidden(name + '\n' + message + (stack ? '\n' + stack : ''), 'ERROR');
});
}
connect() {
this.WebSocket.connect();
}
onConnectionChange(callBack, key = null) {
this.addListener(Enum_1.Listeners.xapi_onConnectionChange, callBack, key);
}
setConnectionStatus(status) {
this.resetMessageTube();
this.openTimeout.clear();
this.pingTimeout.clear();
this.status = status;
if (status === Enum_1.ConnectionStatus.CONNECTING) {
if (this.session.length > 0) {
this.pingTimeout.setTimeout(() => {
this.ping().catch(e => {
Log_1.Log.error('Stream: ping request failed (StreamConnection.ts:64)');
});
}, 100);
}
this.openTimeout.setTimeout(() => {
this.status = Enum_1.ConnectionStatus.CONNECTED;
}, 1000);
}
else {
for (const transactionId in this.transactions) {
if (this.transactions[transactionId].status === Enum_1.TransactionStatus.waiting) {
this.rejectTransaction({
code: Enum_1.errorCode.XAPINODE_1,
explain: 'Stream closed'
}, this.transactions[transactionId], false);
}
}
}
}
sendCommand(command, completion = {}, urgent = false) {
return new Promise((resolve, reject) => {
const transaction = this.addTransaction({
command,
json: JSON.stringify(Object.assign({ command, 'streamSessionId': this.session }, completion)),
args: completion,
transactionId: this.createTransactionId(),
resolve,
reject,
urgent
});
if (transaction.request.json.length > 1000) {
this.rejectTransaction({
code: Enum_1.errorCode.XAPINODE_0,
explain: 'Each command invocation should not contain more than 1kB of data.'
}, transaction);
}
else if (this.status === Enum_1.ConnectionStatus.DISCONNECTED) {
this.rejectTransaction({
code: Enum_1.errorCode.XAPINODE_1,
explain: 'Stream closed'
}, transaction);
}
else if (this.session.length === 0) {
this.rejectTransaction({
code: Enum_1.errorCode.XAPINODE_BE103,
explain: 'User is not logged'
}, transaction);
}
else {
this.sendMessage(transaction, true);
}
});
}
closeConnection() {
this.WebSocket.close();
}
ping() {
return this.sendCommand('ping', {}, true);
}
sendSubscribe(command, completion = {}) {
return this.sendCommand(`get${command}`, completion);
}
sendUnsubscribe(command, completion = {}) {
return this.sendCommand(`stop${command}`, completion);
}
}
exports.StreamConnection = StreamConnection;
//# sourceMappingURL=StreamConnection.js.map