api_connect_nodejs 2.0.13 → 2.0.14
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 +30 -30
- package/conf/settings.ini +17 -20
- package/enums/actionType.js +10 -10
- package/enums/assetType.js +25 -25
- package/enums/chartExchangeType.js +16 -16
- package/enums/chartType.js +13 -13
- package/enums/eodIntervalType.js +11 -11
- package/enums/exchangeType.js +15 -15
- package/enums/intradayIntervalType.js +14 -14
- package/enums/marketCapType.js +12 -12
- package/enums/orderType.js +21 -21
- package/enums/productType.js +24 -24
- package/enums/segementsType.js +13 -13
- package/enums/segmentType.js +10 -10
- package/enums/streamingConstants.js +13 -13
- package/enums/termsType.js +12 -12
- package/enums/validity.js +22 -22
- package/index.js +3 -3
- package/package.json +25 -25
- package/src/apiConnect.js +2682 -2559
- package/src/apiUtils.js +221 -221
- package/src/chart.js +404 -404
- package/src/config.js +347 -342
- package/src/feed/depthFeed.js +136 -136
- package/src/feed/feed.js +170 -170
- package/src/feed/liveNewsFeed.js +112 -112
- package/src/feed/miniQuoteFeed.js +122 -121
- package/src/feed/ordersFeed.js +125 -124
- package/src/feed/quotesFeed.js +123 -122
- package/src/http.js +260 -197
- package/src/iniparser.js +45 -45
- package/src/liveNews.js +362 -362
- package/src/logger.js +16 -16
- package/src/order.js +48 -48
- package/src/quote.js +75 -75
- package/src/report.js +49 -49
- package/src/researchCalls.js +175 -175
- package/src/watchlist.js +378 -378
- package/validations/apiConnectValidator.js +701 -698
- package/validations/chartValidator.js +125 -125
- package/validations/feedStreamerValidator.js +162 -162
- package/validations/liveNewsValidator.js +60 -60
- package/validations/quoteValidator.js +19 -19
- package/validations/reportValidator.js +35 -35
- package/validations/researchCallsValidator.js +86 -86
- package/validations/watchlistValidator.js +60 -60
package/src/feed/depthFeed.js
CHANGED
|
@@ -1,137 +1,137 @@
|
|
|
1
|
-
const log4js = require("../logger");
|
|
2
|
-
const configData = require("../iniparser");
|
|
3
|
-
const { DEPTH_SREAM_REQ_CODE } = require("../../enums/streamingConstants");
|
|
4
|
-
const {
|
|
5
|
-
validateSubscribeDepthFeed,
|
|
6
|
-
} = require("../../validations/feedStreamerValidator");
|
|
7
|
-
|
|
8
|
-
class DepthFeed {
|
|
9
|
-
/**
|
|
10
|
-
* Streamer
|
|
11
|
-
* DepthFeed Class for subsribe or unsubsribe Depth
|
|
12
|
-
*/
|
|
13
|
-
constructor(feed, constantsObj) {
|
|
14
|
-
this.feed = feed;
|
|
15
|
-
this.constants = constantsObj
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* QutoesFeed RequestBody Structure
|
|
20
|
-
* Return DepthFeed RequestBody Structure
|
|
21
|
-
* @function depthFeedRequestBody
|
|
22
|
-
* @returns object
|
|
23
|
-
*/
|
|
24
|
-
requestBody = () => {
|
|
25
|
-
return {
|
|
26
|
-
request: {
|
|
27
|
-
streaming_type: "quote2",
|
|
28
|
-
data: {
|
|
29
|
-
"accType": "EQ",
|
|
30
|
-
symbols: [],
|
|
31
|
-
},
|
|
32
|
-
formFactor: configData.formFactor,
|
|
33
|
-
appID: configData.ApiIdKey,
|
|
34
|
-
response_format: "json",
|
|
35
|
-
request_type: "",
|
|
36
|
-
},
|
|
37
|
-
echo: {},
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Create DepthFeed RequestBody
|
|
43
|
-
* Return DepthFeed RequestBody
|
|
44
|
-
* @function createDepthFeedRequest
|
|
45
|
-
* @param {Object[]} symbols - Array of subsribe Symbols
|
|
46
|
-
* @param {boolean} order - true for subsribe and false for unsubsribe
|
|
47
|
-
* @returns object
|
|
48
|
-
*/
|
|
49
|
-
createDepthFeedRequest = (symbols, depth = false) => {
|
|
50
|
-
let body = {};
|
|
51
|
-
const accTyp = this.constants.Data.data.lgnData.accTyp;
|
|
52
|
-
try {
|
|
53
|
-
body = this.requestBody();
|
|
54
|
-
const symset = symbols.map((sym) => ({
|
|
55
|
-
symbol: sym.trim()
|
|
56
|
-
}));
|
|
57
|
-
const substrMcx = '_MCX';
|
|
58
|
-
const substrNcdex = '_NCDEX';
|
|
59
|
-
const subArrContainsMcx = symbols.some(str =>
|
|
60
|
-
(str.toUpperCase()).includes(substrMcx)
|
|
61
|
-
);
|
|
62
|
-
const subArrContainsNcx = symbols.some(str => (str.toUpperCase()).includes(substrNcdex));
|
|
63
|
-
|
|
64
|
-
if ((subArrContainsMcx || subArrContainsNcx) && accTyp == 'EQ') {
|
|
65
|
-
body = {"account_type_exception" : "Symbol subscription error"}
|
|
66
|
-
}else {
|
|
67
|
-
body.request.data.symbols = symset;
|
|
68
|
-
|
|
69
|
-
if (depth) {
|
|
70
|
-
body.request.request_type = "subscribe";
|
|
71
|
-
} else {
|
|
72
|
-
body.request.request_type = "unsubscribe";
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
} catch (error) {
|
|
76
|
-
log4js.debug("createDepthFeedRequest error - " + error);
|
|
77
|
-
} finally {
|
|
78
|
-
return body;
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* To subscribe to the streamer, Create the single instance of this mentioning `callback` method. After successsful subscription, `callback` method will be called whenever packet is available at the streamer.
|
|
84
|
-
* @async
|
|
85
|
-
* @function subscribeDepthFeed
|
|
86
|
-
* @param {(err?, data?, close?: number) => void} callBack Callback to receive the Feed in
|
|
87
|
-
* @param {Array<string>} symbols Symbol list for subscription: Symbol_exchange to be obtained from Contract File
|
|
88
|
-
* @returns
|
|
89
|
-
*/
|
|
90
|
-
subscribeDepthFeed = async (symbols, callback) => {
|
|
91
|
-
try {
|
|
92
|
-
/** Validation Start */
|
|
93
|
-
const validateResponse = validateSubscribeDepthFeed(callback, symbols);
|
|
94
|
-
|
|
95
|
-
if (validateResponse.error) {
|
|
96
|
-
log4js.debug(
|
|
97
|
-
"subscribeDepthFeed validation error - " +
|
|
98
|
-
validateResponse.error.details
|
|
99
|
-
);
|
|
100
|
-
return Promise.reject(validateResponse.error.details);
|
|
101
|
-
}
|
|
102
|
-
/** Validation End */
|
|
103
|
-
|
|
104
|
-
/** Create Streaming Depth Request */
|
|
105
|
-
let depthRequest = this.createDepthFeedRequest(symbols, true);
|
|
106
|
-
if(Object.keys(depthRequest).includes("account_type_exception")) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
/** Call connect method of Feed Class */
|
|
110
|
-
this.feed.subsribe(DEPTH_SREAM_REQ_CODE, depthRequest, callback);
|
|
111
|
-
} catch (error) {
|
|
112
|
-
log4js.debug("subscribeDepthFeed error - " + error);
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* This method will unsubscribe the symbols from the streamer. After successful invokation of this, will stop the streamer packets of these symbols.
|
|
118
|
-
* @async
|
|
119
|
-
* @function unsubscribeDepthFeed
|
|
120
|
-
* @returns
|
|
121
|
-
*/
|
|
122
|
-
unsubscribeDepthFeed = async () => {
|
|
123
|
-
try {
|
|
124
|
-
/** Get Streaming Depth Request */
|
|
125
|
-
const depthRequest = this.createDepthFeedRequest([]);
|
|
126
|
-
if(Object.keys(depthRequest).includes("account_type_exception")) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
/** Unsubsribe symbols */
|
|
130
|
-
this.feed.unsubsribe(DEPTH_SREAM_REQ_CODE, depthRequest);
|
|
131
|
-
} catch (error) {
|
|
132
|
-
log4js.debug("unsubscribeDepthFeed error - " + error);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
1
|
+
const log4js = require("../logger");
|
|
2
|
+
const configData = require("../iniparser");
|
|
3
|
+
const { DEPTH_SREAM_REQ_CODE } = require("../../enums/streamingConstants");
|
|
4
|
+
const {
|
|
5
|
+
validateSubscribeDepthFeed,
|
|
6
|
+
} = require("../../validations/feedStreamerValidator");
|
|
7
|
+
|
|
8
|
+
class DepthFeed {
|
|
9
|
+
/**
|
|
10
|
+
* Streamer
|
|
11
|
+
* DepthFeed Class for subsribe or unsubsribe Depth
|
|
12
|
+
*/
|
|
13
|
+
constructor(feed, constantsObj) {
|
|
14
|
+
this.feed = feed;
|
|
15
|
+
this.constants = constantsObj
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* QutoesFeed RequestBody Structure
|
|
20
|
+
* Return DepthFeed RequestBody Structure
|
|
21
|
+
* @function depthFeedRequestBody
|
|
22
|
+
* @returns object
|
|
23
|
+
*/
|
|
24
|
+
requestBody = () => {
|
|
25
|
+
return {
|
|
26
|
+
request: {
|
|
27
|
+
streaming_type: "quote2",
|
|
28
|
+
data: {
|
|
29
|
+
"accType": this.constants.Data.data.lgnData.accTyp, //"EQ",
|
|
30
|
+
symbols: [],
|
|
31
|
+
},
|
|
32
|
+
formFactor: configData.formFactor,
|
|
33
|
+
appID: configData.ApiIdKey,
|
|
34
|
+
response_format: "json",
|
|
35
|
+
request_type: "",
|
|
36
|
+
},
|
|
37
|
+
echo: {},
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Create DepthFeed RequestBody
|
|
43
|
+
* Return DepthFeed RequestBody
|
|
44
|
+
* @function createDepthFeedRequest
|
|
45
|
+
* @param {Object[]} symbols - Array of subsribe Symbols
|
|
46
|
+
* @param {boolean} order - true for subsribe and false for unsubsribe
|
|
47
|
+
* @returns object
|
|
48
|
+
*/
|
|
49
|
+
createDepthFeedRequest = (symbols, depth = false) => {
|
|
50
|
+
let body = {};
|
|
51
|
+
const accTyp = this.constants.Data.data.lgnData.accTyp;
|
|
52
|
+
try {
|
|
53
|
+
body = this.requestBody();
|
|
54
|
+
const symset = symbols.map((sym) => ({
|
|
55
|
+
symbol: sym.trim()
|
|
56
|
+
}));
|
|
57
|
+
const substrMcx = '_MCX';
|
|
58
|
+
const substrNcdex = '_NCDEX';
|
|
59
|
+
const subArrContainsMcx = symbols.some(str =>
|
|
60
|
+
(str.toUpperCase()).includes(substrMcx)
|
|
61
|
+
);
|
|
62
|
+
const subArrContainsNcx = symbols.some(str => (str.toUpperCase()).includes(substrNcdex));
|
|
63
|
+
|
|
64
|
+
if ((subArrContainsMcx || subArrContainsNcx) && accTyp == 'EQ') {
|
|
65
|
+
body = {"account_type_exception" : "Symbol subscription error"}
|
|
66
|
+
}else {
|
|
67
|
+
body.request.data.symbols = symset;
|
|
68
|
+
|
|
69
|
+
if (depth) {
|
|
70
|
+
body.request.request_type = "subscribe";
|
|
71
|
+
} else {
|
|
72
|
+
body.request.request_type = "unsubscribe";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
log4js.debug("createDepthFeedRequest error - " + error);
|
|
77
|
+
} finally {
|
|
78
|
+
return body;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* To subscribe to the streamer, Create the single instance of this mentioning `callback` method. After successsful subscription, `callback` method will be called whenever packet is available at the streamer.
|
|
84
|
+
* @async
|
|
85
|
+
* @function subscribeDepthFeed
|
|
86
|
+
* @param {(err?, data?, close?: number) => void} callBack Callback to receive the Feed in
|
|
87
|
+
* @param {Array<string>} symbols Symbol list for subscription: Symbol_exchange to be obtained from Contract File
|
|
88
|
+
* @returns
|
|
89
|
+
*/
|
|
90
|
+
subscribeDepthFeed = async (symbols, callback) => {
|
|
91
|
+
try {
|
|
92
|
+
/** Validation Start */
|
|
93
|
+
const validateResponse = validateSubscribeDepthFeed(callback, symbols);
|
|
94
|
+
|
|
95
|
+
if (validateResponse.error) {
|
|
96
|
+
log4js.debug(
|
|
97
|
+
"subscribeDepthFeed validation error - " +
|
|
98
|
+
validateResponse.error.details
|
|
99
|
+
);
|
|
100
|
+
return Promise.reject(validateResponse.error.details);
|
|
101
|
+
}
|
|
102
|
+
/** Validation End */
|
|
103
|
+
|
|
104
|
+
/** Create Streaming Depth Request */
|
|
105
|
+
let depthRequest = this.createDepthFeedRequest(symbols, true);
|
|
106
|
+
if(Object.keys(depthRequest).includes("account_type_exception")) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
/** Call connect method of Feed Class */
|
|
110
|
+
this.feed.subsribe(DEPTH_SREAM_REQ_CODE, depthRequest, callback);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
log4js.debug("subscribeDepthFeed error - " + error);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* This method will unsubscribe the symbols from the streamer. After successful invokation of this, will stop the streamer packets of these symbols.
|
|
118
|
+
* @async
|
|
119
|
+
* @function unsubscribeDepthFeed
|
|
120
|
+
* @returns
|
|
121
|
+
*/
|
|
122
|
+
unsubscribeDepthFeed = async () => {
|
|
123
|
+
try {
|
|
124
|
+
/** Get Streaming Depth Request */
|
|
125
|
+
const depthRequest = this.createDepthFeedRequest([]);
|
|
126
|
+
if(Object.keys(depthRequest).includes("account_type_exception")) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
/** Unsubsribe symbols */
|
|
130
|
+
this.feed.unsubsribe(DEPTH_SREAM_REQ_CODE, depthRequest);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
log4js.debug("unsubscribeDepthFeed error - " + error);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
137
|
module.exports = DepthFeed;
|
package/src/feed/feed.js
CHANGED
|
@@ -1,170 +1,170 @@
|
|
|
1
|
-
const net = require("net");
|
|
2
|
-
const configData = require("../iniparser");
|
|
3
|
-
const log4js = require("../logger");
|
|
4
|
-
const streamingConstants = require("../../enums/streamingConstants");
|
|
5
|
-
class Feed {
|
|
6
|
-
/**
|
|
7
|
-
* Streamer
|
|
8
|
-
*
|
|
9
|
-
* To subscribe to the streamer, Create the single instance of this mentioning `callback` method. After successsful subscription, `callback` method will be called whenever packet is available at the streamer.
|
|
10
|
-
* @param {string} userid User ID
|
|
11
|
-
* @param {(err?, data?, close?: number) => void} callBack Callback to receive the Feed in
|
|
12
|
-
* @param {boolean} subscribe_order
|
|
13
|
-
* @param {boolean} subscribe_quote
|
|
14
|
-
*/
|
|
15
|
-
constructor() {
|
|
16
|
-
this.sock = new net.Socket();
|
|
17
|
-
this.status = false;
|
|
18
|
-
const heartBeatTimer = 0;
|
|
19
|
-
this.init();
|
|
20
|
-
this.requestsList = {};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
init = () => {
|
|
24
|
-
this.connect();
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
connect = () => {
|
|
28
|
-
const hostName = configData.hostName;
|
|
29
|
-
const port = configData.port;
|
|
30
|
-
try {
|
|
31
|
-
this.sock.connect(port, hostName, () => {
|
|
32
|
-
this.clearIntervalConnect();
|
|
33
|
-
log4js.debug("connected to server!");
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
this.sock.on("data", (data) => {
|
|
37
|
-
try {
|
|
38
|
-
let result = data.toString();
|
|
39
|
-
const obj = JSON.parse(result)
|
|
40
|
-
const streamingType = obj['response']['streaming_type']
|
|
41
|
-
if (result) {
|
|
42
|
-
if (
|
|
43
|
-
streamingType.toLowerCase() == "orderFiler".toLowerCase()
|
|
44
|
-
) {
|
|
45
|
-
let callbackMethod =
|
|
46
|
-
this.requestsList[streamingConstants.ORDER_STREAM_REQ_CODE][
|
|
47
|
-
"callback"
|
|
48
|
-
];
|
|
49
|
-
callbackMethod(null, result, null);
|
|
50
|
-
} else if (
|
|
51
|
-
streamingType.toLowerCase() == "quote".toLowerCase()
|
|
52
|
-
) {
|
|
53
|
-
let callbackMethod =
|
|
54
|
-
this.requestsList[streamingConstants.REDUCED_QUOTE_SREAM_REQ_CODE][
|
|
55
|
-
"callback"
|
|
56
|
-
];
|
|
57
|
-
callbackMethod(null, result, null);
|
|
58
|
-
} else if (
|
|
59
|
-
streamingType.toLowerCase() == "miniquote".toLowerCase()
|
|
60
|
-
) {
|
|
61
|
-
let callbackMethod =
|
|
62
|
-
this.requestsList[streamingConstants.MINI_QUOTE_SREAM_REQ_CODE][
|
|
63
|
-
"callback"
|
|
64
|
-
];
|
|
65
|
-
callbackMethod(null, result, null);
|
|
66
|
-
} else if (
|
|
67
|
-
streamingType.toLowerCase() == "quote2".toLowerCase()
|
|
68
|
-
) {
|
|
69
|
-
let callbackMethod =
|
|
70
|
-
this.requestsList[streamingConstants.DEPTH_SREAM_REQ_CODE][
|
|
71
|
-
"callback"
|
|
72
|
-
];
|
|
73
|
-
callbackMethod(null, result, null);
|
|
74
|
-
}else if (
|
|
75
|
-
streamingType.toLowerCase() == "news".toLowerCase()
|
|
76
|
-
) {
|
|
77
|
-
let callbackMethod =
|
|
78
|
-
this.requestsList[streamingConstants.LIVENEWS_STREAM_REQ_CODE][
|
|
79
|
-
"callback"
|
|
80
|
-
];
|
|
81
|
-
callbackMethod(null, result, null);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
} catch (error) {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
this.sock.on("end", (val) => {
|
|
90
|
-
this.reconnect();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this.sock.on("error", (err) => {
|
|
94
|
-
log4js.debug("connection error " + err);
|
|
95
|
-
// requestObj.callback(err, null, null);
|
|
96
|
-
this.reconnect();
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
this.sock.on("close", (val) => {
|
|
100
|
-
log4js.debug("connection closed " + val);
|
|
101
|
-
this.reconnect();
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
} catch (error) {
|
|
105
|
-
log4js.debug("connect error is " + error);
|
|
106
|
-
this.reconnect();
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
clearIntervalConnect = () => {
|
|
111
|
-
if (false === this.status) return;
|
|
112
|
-
clearInterval(this.status);
|
|
113
|
-
this.status = false;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
reconnect = () => {
|
|
117
|
-
log4js.debug("reconnecting...");
|
|
118
|
-
|
|
119
|
-
if (this.status) return;
|
|
120
|
-
this.status = setInterval(() => {
|
|
121
|
-
this.sock.removeAllListeners();
|
|
122
|
-
this.connect();
|
|
123
|
-
}, 3000);
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
subsribe = (streamingConstants, request, callBack, heartBeatFeed = false) => {
|
|
127
|
-
const requestObj = {
|
|
128
|
-
request: request,
|
|
129
|
-
callback: callBack,
|
|
130
|
-
};
|
|
131
|
-
this.requestsList[streamingConstants] = requestObj;
|
|
132
|
-
this.readWriteStreamData(requestObj, heartBeatFeed);
|
|
133
|
-
this.checkAndStartHeartBeat()
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
unsubsribe = (streamingConstants, request, heartBeatFeed = false) => {
|
|
137
|
-
const requestObj = {
|
|
138
|
-
request: request,
|
|
139
|
-
callback: this.requestsList[streamingConstants].callback,
|
|
140
|
-
};
|
|
141
|
-
this.readWriteStreamData(requestObj, heartBeatFeed);
|
|
142
|
-
delete this.requestsList[streamingConstants];
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
readWriteStreamData = (requestObj, heartBeatFeed= false) => {
|
|
146
|
-
|
|
147
|
-
try {
|
|
148
|
-
if(heartBeatFeed) {
|
|
149
|
-
this.sock.write("{}" + "\n");
|
|
150
|
-
} else {
|
|
151
|
-
this.sock.write(JSON.stringify(requestObj.request) + "\n");
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
} catch (error) {
|
|
155
|
-
console.log({ error });
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
checkAndStartHeartBeat = () => {
|
|
160
|
-
|
|
161
|
-
if(this.heartBeatTimer) {
|
|
162
|
-
// Clearing the interval timer
|
|
163
|
-
clearInterval(this.heartBeatTimer);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
this.heartBeatTimer = setInterval(this.readWriteStreamData, 90000, undefined, true);
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
module.exports = Feed;
|
|
1
|
+
const net = require("net");
|
|
2
|
+
const configData = require("../iniparser");
|
|
3
|
+
const log4js = require("../logger");
|
|
4
|
+
const streamingConstants = require("../../enums/streamingConstants");
|
|
5
|
+
class Feed {
|
|
6
|
+
/**
|
|
7
|
+
* Streamer
|
|
8
|
+
*
|
|
9
|
+
* To subscribe to the streamer, Create the single instance of this mentioning `callback` method. After successsful subscription, `callback` method will be called whenever packet is available at the streamer.
|
|
10
|
+
* @param {string} userid User ID
|
|
11
|
+
* @param {(err?, data?, close?: number) => void} callBack Callback to receive the Feed in
|
|
12
|
+
* @param {boolean} subscribe_order
|
|
13
|
+
* @param {boolean} subscribe_quote
|
|
14
|
+
*/
|
|
15
|
+
constructor() {
|
|
16
|
+
this.sock = new net.Socket();
|
|
17
|
+
this.status = false;
|
|
18
|
+
const heartBeatTimer = 0;
|
|
19
|
+
this.init();
|
|
20
|
+
this.requestsList = {};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
init = () => {
|
|
24
|
+
this.connect();
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
connect = () => {
|
|
28
|
+
const hostName = configData.hostName;
|
|
29
|
+
const port = configData.port;
|
|
30
|
+
try {
|
|
31
|
+
this.sock.connect(port, hostName, () => {
|
|
32
|
+
this.clearIntervalConnect();
|
|
33
|
+
log4js.debug("connected to server!");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
this.sock.on("data", (data) => {
|
|
37
|
+
try {
|
|
38
|
+
let result = data.toString();
|
|
39
|
+
const obj = JSON.parse(result)
|
|
40
|
+
const streamingType = obj['response']['streaming_type']
|
|
41
|
+
if (result) {
|
|
42
|
+
if (
|
|
43
|
+
streamingType.toLowerCase() == "orderFiler".toLowerCase()
|
|
44
|
+
) {
|
|
45
|
+
let callbackMethod =
|
|
46
|
+
this.requestsList[streamingConstants.ORDER_STREAM_REQ_CODE][
|
|
47
|
+
"callback"
|
|
48
|
+
];
|
|
49
|
+
callbackMethod(null, result, null);
|
|
50
|
+
} else if (
|
|
51
|
+
streamingType.toLowerCase() == "quote".toLowerCase()
|
|
52
|
+
) {
|
|
53
|
+
let callbackMethod =
|
|
54
|
+
this.requestsList[streamingConstants.REDUCED_QUOTE_SREAM_REQ_CODE][
|
|
55
|
+
"callback"
|
|
56
|
+
];
|
|
57
|
+
callbackMethod(null, result, null);
|
|
58
|
+
} else if (
|
|
59
|
+
streamingType.toLowerCase() == "miniquote".toLowerCase()
|
|
60
|
+
) {
|
|
61
|
+
let callbackMethod =
|
|
62
|
+
this.requestsList[streamingConstants.MINI_QUOTE_SREAM_REQ_CODE][
|
|
63
|
+
"callback"
|
|
64
|
+
];
|
|
65
|
+
callbackMethod(null, result, null);
|
|
66
|
+
} else if (
|
|
67
|
+
streamingType.toLowerCase() == "quote2".toLowerCase()
|
|
68
|
+
) {
|
|
69
|
+
let callbackMethod =
|
|
70
|
+
this.requestsList[streamingConstants.DEPTH_SREAM_REQ_CODE][
|
|
71
|
+
"callback"
|
|
72
|
+
];
|
|
73
|
+
callbackMethod(null, result, null);
|
|
74
|
+
}else if (
|
|
75
|
+
streamingType.toLowerCase() == "news".toLowerCase()
|
|
76
|
+
) {
|
|
77
|
+
let callbackMethod =
|
|
78
|
+
this.requestsList[streamingConstants.LIVENEWS_STREAM_REQ_CODE][
|
|
79
|
+
"callback"
|
|
80
|
+
];
|
|
81
|
+
callbackMethod(null, result, null);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
this.sock.on("end", (val) => {
|
|
90
|
+
this.reconnect();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
this.sock.on("error", (err) => {
|
|
94
|
+
log4js.debug("connection error " + err);
|
|
95
|
+
// requestObj.callback(err, null, null);
|
|
96
|
+
this.reconnect();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
this.sock.on("close", (val) => {
|
|
100
|
+
log4js.debug("connection closed " + val);
|
|
101
|
+
this.reconnect();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
} catch (error) {
|
|
105
|
+
log4js.debug("connect error is " + error);
|
|
106
|
+
this.reconnect();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
clearIntervalConnect = () => {
|
|
111
|
+
if (false === this.status) return;
|
|
112
|
+
clearInterval(this.status);
|
|
113
|
+
this.status = false;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
reconnect = () => {
|
|
117
|
+
log4js.debug("reconnecting...");
|
|
118
|
+
|
|
119
|
+
if (this.status) return;
|
|
120
|
+
this.status = setInterval(() => {
|
|
121
|
+
this.sock.removeAllListeners();
|
|
122
|
+
this.connect();
|
|
123
|
+
}, 3000);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
subsribe = (streamingConstants, request, callBack, heartBeatFeed = false) => {
|
|
127
|
+
const requestObj = {
|
|
128
|
+
request: request,
|
|
129
|
+
callback: callBack,
|
|
130
|
+
};
|
|
131
|
+
this.requestsList[streamingConstants] = requestObj;
|
|
132
|
+
this.readWriteStreamData(requestObj, heartBeatFeed);
|
|
133
|
+
this.checkAndStartHeartBeat()
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
unsubsribe = (streamingConstants, request, heartBeatFeed = false) => {
|
|
137
|
+
const requestObj = {
|
|
138
|
+
request: request,
|
|
139
|
+
callback: this.requestsList[streamingConstants].callback,
|
|
140
|
+
};
|
|
141
|
+
this.readWriteStreamData(requestObj, heartBeatFeed);
|
|
142
|
+
delete this.requestsList[streamingConstants];
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
readWriteStreamData = (requestObj, heartBeatFeed= false) => {
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
if(heartBeatFeed) {
|
|
149
|
+
this.sock.write("{}" + "\n");
|
|
150
|
+
} else {
|
|
151
|
+
this.sock.write(JSON.stringify(requestObj.request) + "\n");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.log({ error });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
checkAndStartHeartBeat = () => {
|
|
160
|
+
|
|
161
|
+
if(this.heartBeatTimer) {
|
|
162
|
+
// Clearing the interval timer
|
|
163
|
+
clearInterval(this.heartBeatTimer);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
this.heartBeatTimer = setInterval(this.readWriteStreamData, 90000, undefined, true);
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
module.exports = Feed;
|