grexxconnect-ess 1.1.2 → 1.2.2
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/client.js +4 -0
- package/index.js +103 -27
- package/package.json +3 -2
- package/schema/client.d.ts +26 -0
- package/schema/index.d.ts +21 -0
package/client.js
CHANGED
|
@@ -91,6 +91,10 @@ class WebSocketClient extends EventEmitter {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
disconnect(code, message) {
|
|
95
|
+
this.instance.close(code, message);
|
|
96
|
+
}
|
|
97
|
+
|
|
94
98
|
reconnect( code, msg ) {
|
|
95
99
|
this.log('connection failed'.red, `retry in ${this.autoReconnectInterval}ms`, code.toString().red, (msg || '').yellow);
|
|
96
100
|
this.instance.removeAllListeners();
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (C) 2014-
|
|
2
|
+
* Copyright (C) 2014-2022 Grexx - All Rights Reserved
|
|
3
3
|
* Unauthorized copying of this file, via any medium is strictly prohibited
|
|
4
4
|
* Proprietary and confidential
|
|
5
5
|
*/
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
const EventEmitter = require('events');
|
|
9
9
|
const WebSocket = require('./client');
|
|
10
10
|
|
|
11
|
+
const TIMEOUT_LONG = 30 * 1000; //== 30 seconds
|
|
12
|
+
|
|
11
13
|
class EssConnect extends EventEmitter {
|
|
12
|
-
constructor(
|
|
14
|
+
constructor(settings) {
|
|
13
15
|
super();
|
|
14
16
|
|
|
15
17
|
const thisVersion = require('./package.json').version;
|
|
@@ -21,29 +23,95 @@ class EssConnect extends EventEmitter {
|
|
|
21
23
|
debug: settings.debug
|
|
22
24
|
});
|
|
23
25
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
+
const _waitQueue = {},
|
|
27
|
+
_unfinishedResponses = {};
|
|
28
|
+
|
|
29
|
+
const send = (type, content, timeout = TIMEOUT_LONG) => {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const essCorrelationId = content?.['ess-correlation-id'];
|
|
32
|
+
|
|
33
|
+
if (!essCorrelationId || !this._ackFunctional) {
|
|
34
|
+
try {
|
|
35
|
+
ws.send(JSON.stringify({
|
|
36
|
+
type: type,
|
|
37
|
+
content: content,
|
|
38
|
+
timestamp: Date.now()
|
|
39
|
+
}));
|
|
40
|
+
return resolve();
|
|
41
|
+
} catch (error) {
|
|
42
|
+
return reject(error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const exceededTimeout = setTimeout(async () => {
|
|
47
|
+
ws.debug(`timeout of ${timeout}ms exceeded for ack response from server`);
|
|
48
|
+
return reject('Timeout exceeded');
|
|
49
|
+
}, timeout);
|
|
50
|
+
|
|
51
|
+
_waitQueue[essCorrelationId] = () => {
|
|
52
|
+
clearTimeout(exceededTimeout);
|
|
53
|
+
ws.debug(`ack response received from server`);
|
|
54
|
+
return resolve('Ack response received from server');
|
|
55
|
+
};
|
|
56
|
+
|
|
26
57
|
ws.send(JSON.stringify({
|
|
27
58
|
type: type,
|
|
28
59
|
content: content,
|
|
29
60
|
timestamp: Date.now()
|
|
30
|
-
}), error => {
|
|
31
|
-
if (
|
|
32
|
-
reject(error);
|
|
33
|
-
} else {
|
|
34
|
-
resolve();
|
|
61
|
+
}), (error) => {
|
|
62
|
+
if (error) {
|
|
63
|
+
return reject(error);
|
|
35
64
|
}
|
|
36
65
|
});
|
|
37
66
|
});
|
|
38
67
|
};
|
|
39
68
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
69
|
+
const sendAck = async (connectCorrelationId, message = '', type = 'ack') => {
|
|
70
|
+
this.ws.debug(`acknowledging message from server for message header ID: ${connectCorrelationId}`.gray);
|
|
71
|
+
await send(type, {'connect-correlation-id': connectCorrelationId, message});
|
|
72
|
+
this.emit(type);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const completeUnfinishedResponses = () => {
|
|
76
|
+
this.ws.debug(`checking for any incomplete message responses: ${Object.keys(_unfinishedResponses).length.toString().blue} unfinished responses`);
|
|
77
|
+
for (const key in _unfinishedResponses) {
|
|
78
|
+
const {type, content} = _unfinishedResponses[key];
|
|
79
|
+
send(type, content).then(() => {
|
|
80
|
+
delete _unfinishedResponses[key];
|
|
81
|
+
}).catch(() => handleTimeout(type, content));
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const handleTimeout = (type, content) => {
|
|
86
|
+
const id = content['ess-correlation-id'];
|
|
87
|
+
_unfinishedResponses[id] = {type, content};
|
|
88
|
+
ws.disconnect(1012, "Ack response from server timed out");
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
ws.on('close', (code, msg) => this.emit('disconnected', code, msg));
|
|
92
|
+
ws.on('message', async (_message) => {
|
|
93
|
+
const connectCorrelationId = _message['connect-correlation-id'],
|
|
94
|
+
essCorrelationId = _message['ess-correlation-id'];
|
|
95
|
+
|
|
96
|
+
switch (_message.type) {
|
|
43
97
|
case 'ping':
|
|
44
|
-
this.ws.debug('responding to connection-ping');
|
|
45
|
-
send('pong');
|
|
98
|
+
this.ws.debug('responding to connection-ping'.gray);
|
|
46
99
|
this.emit('ping');
|
|
100
|
+
await send('pong');
|
|
101
|
+
break;
|
|
102
|
+
case 'ackFunctional':
|
|
103
|
+
this.ws.debug('responding to functionality check'.green, 'acknowledgements'.blue);
|
|
104
|
+
this._ackFunctional = true;
|
|
105
|
+
await sendAck(connectCorrelationId, null, 'ackFunctional');
|
|
106
|
+
completeUnfinishedResponses();
|
|
107
|
+
break;
|
|
108
|
+
case 'ack':
|
|
109
|
+
this.ws.debug(`received ack from GrexxConnect for message with header ID: ${essCorrelationId}`);
|
|
110
|
+
if (typeof (essCorrelationId) != 'undefined' && typeof (_waitQueue[essCorrelationId]) == 'function') {
|
|
111
|
+
const execFunc = _waitQueue[essCorrelationId];
|
|
112
|
+
execFunc();
|
|
113
|
+
delete _waitQueue[essCorrelationId];
|
|
114
|
+
}
|
|
47
115
|
break;
|
|
48
116
|
case 'authorized':
|
|
49
117
|
this.log('connected and authorized for'.green, _message.namespace.blue);
|
|
@@ -56,19 +124,27 @@ class EssConnect extends EventEmitter {
|
|
|
56
124
|
this.handleSystemMessage(_message, send);
|
|
57
125
|
break;
|
|
58
126
|
case'message':
|
|
127
|
+
await sendAck(connectCorrelationId, "message received and being processed");
|
|
59
128
|
this.emit('message', {
|
|
60
129
|
content: _message.content,
|
|
61
130
|
parsed: this.parseMessage(_message.content.data),
|
|
62
131
|
resolve: outputData => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
132
|
+
const type = 'response',
|
|
133
|
+
content = {
|
|
134
|
+
'ess-correlation-id': connectCorrelationId,
|
|
135
|
+
toMessage: _message,
|
|
136
|
+
outputData: outputData
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
return send(type, content).catch(() => {
|
|
140
|
+
handleTimeout(type, content);
|
|
66
141
|
});
|
|
67
142
|
},
|
|
68
|
-
reject: (
|
|
143
|
+
reject: (publicMessage, debugMessage, additionalContext) => {
|
|
69
144
|
return send('reject', {
|
|
70
|
-
|
|
71
|
-
|
|
145
|
+
'ess-correlation-id': connectCorrelationId,
|
|
146
|
+
toMessage: _message,
|
|
147
|
+
errorContext: Object.assign({
|
|
72
148
|
publicMessage,
|
|
73
149
|
debugMessage
|
|
74
150
|
}, additionalContext)
|
|
@@ -99,27 +175,27 @@ class EssConnect extends EventEmitter {
|
|
|
99
175
|
/**Set a monitoring function. Should return {status:'ok|warning|error', ...}
|
|
100
176
|
* @param {function} statusFunction
|
|
101
177
|
*/
|
|
102
|
-
setMonitoringResponse(
|
|
178
|
+
setMonitoringResponse(statusFunction) {
|
|
103
179
|
this._statusFunction = statusFunction;
|
|
104
180
|
}
|
|
105
181
|
|
|
106
|
-
log(
|
|
182
|
+
log(...args) {
|
|
107
183
|
console.info(' [ESS][MAIN] '.gray, ...args);
|
|
108
184
|
}
|
|
109
185
|
|
|
110
|
-
handleSystemMessage(
|
|
111
|
-
if (
|
|
112
|
-
this.ws.debug('responding to system-ping');
|
|
186
|
+
handleSystemMessage(message, send) {
|
|
187
|
+
if (message.content.action === 'ping') {
|
|
188
|
+
this.ws.debug('responding to system-ping'.gray);
|
|
113
189
|
send('system', {
|
|
114
190
|
action: 'pong',
|
|
115
191
|
client_data: typeof this._statusFunction === 'function' ?
|
|
116
|
-
this._statusFunction() : {
|
|
192
|
+
this._statusFunction() : {status: 'ok'},
|
|
117
193
|
server_data: message.content.id
|
|
118
194
|
});
|
|
119
195
|
}
|
|
120
196
|
}
|
|
121
197
|
|
|
122
|
-
parseMessage(
|
|
198
|
+
parseMessage(message = []) {
|
|
123
199
|
const result = {};
|
|
124
200
|
|
|
125
201
|
message.forEach(part => {
|
package/package.json
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
"name" : "grexxconnect-ess",
|
|
3
3
|
"author" : "Grexx <info@grexxboxx.com>",
|
|
4
4
|
"description" : "Grexx Connect - External System Service Helper",
|
|
5
|
-
"version" : "1.
|
|
5
|
+
"version" : "1.2.2",
|
|
6
|
+
"types" : "./schema/index.d.ts",
|
|
6
7
|
"contributors" : [
|
|
7
8
|
{
|
|
8
9
|
"name" : "Jeffrey van Norden",
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
],
|
|
12
13
|
"dependencies" : {
|
|
13
14
|
"colors": "1.4",
|
|
14
|
-
"ws" : "7.
|
|
15
|
+
"ws" : "7.5"
|
|
15
16
|
},
|
|
16
17
|
"optionalDependencies": {
|
|
17
18
|
"utf-8-validate": "5.0",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2014-2022 Grexx - All Rights Reserved
|
|
3
|
+
* Unauthorized copying of this file, via any medium is strictly prohibited
|
|
4
|
+
* Proprietary and confidential
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export = WebSocketClient;
|
|
8
|
+
declare class WebSocketClient extends EventEmitter {
|
|
9
|
+
constructor(url: any, options: any);
|
|
10
|
+
number: number;
|
|
11
|
+
autoReconnectInterval: number;
|
|
12
|
+
_debug: any;
|
|
13
|
+
log(...args: any[]): void;
|
|
14
|
+
debug(...args: any[]): void;
|
|
15
|
+
open(url: any, options: any): void;
|
|
16
|
+
url: any;
|
|
17
|
+
options: any;
|
|
18
|
+
instance: any;
|
|
19
|
+
send(data: any, option: any, cb: any): void;
|
|
20
|
+
reconnect(code: any, msg: any): void;
|
|
21
|
+
onOpen(...args: any[]): void;
|
|
22
|
+
onMessage(data: any, flags: any, number: any): void;
|
|
23
|
+
onError(error: any): void;
|
|
24
|
+
onClose(code: any, msg: any): void;
|
|
25
|
+
}
|
|
26
|
+
import EventEmitter from "events";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2014-2022 Grexx - All Rights Reserved
|
|
3
|
+
* Unauthorized copying of this file, via any medium is strictly prohibited
|
|
4
|
+
* Proprietary and confidential
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export = EssConnect;
|
|
8
|
+
declare class EssConnect extends EventEmitter {
|
|
9
|
+
constructor(settings: any);
|
|
10
|
+
ws: WebSocket;
|
|
11
|
+
/**Set a monitoring function. Should return {status:'ok|warning|error', ...}
|
|
12
|
+
* @param {function} statusFunction
|
|
13
|
+
*/
|
|
14
|
+
setMonitoringResponse(statusFunction: Function): void;
|
|
15
|
+
_statusFunction: Function | undefined;
|
|
16
|
+
log(...args: any[]): void;
|
|
17
|
+
handleSystemMessage(message: any, send: any): void;
|
|
18
|
+
parseMessage(message?: any[]): {};
|
|
19
|
+
}
|
|
20
|
+
import EventEmitter from "events";
|
|
21
|
+
import WebSocket = require("./client");
|