unetjs 2.0.9 → 3.0.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 +10 -6
- package/dist/cjs/unet.cjs +69 -52
- package/dist/esm/unet.js +67 -31
- package/dist/unetjs.js +67 -30
- package/dist/unetjs.js.map +1 -1
- package/dist/unetjs.min.js +1 -1
- package/dist/unetjs.min.js.map +1 -1
- package/package.json +11 -12
package/README.md
CHANGED
|
@@ -63,14 +63,18 @@ The JavaScript version of the UnetSocket API allows a user to connect to a node
|
|
|
63
63
|
|
|
64
64
|
The UnetSocket API allows a user to cache responses to parameter requests. This is useful in a scenario where the parameters aren't changing very often, and the user wants to reduce the round trip time for parameter requests.
|
|
65
65
|
|
|
66
|
+
> This behaviour used to be enabled by default in unetsocket.js v2.0.0 till v2.0.10. From v3.0.0 onwards, this behaviour is **disabled** by default but a available as an option.
|
|
67
|
+
|
|
68
|
+
You can use the `CachingGateway` class instead of the `Gateway` class to enable this behaviour.
|
|
69
|
+
|
|
66
70
|
UnetSocket API acheives this using two mechanism, firstly, it can request ALL of the parameters from an Agent instead of just one, and then cache the responses. This is called the `greedy` mode. The greedy mode is enabled by default but can be disabled by setting the `greedy` property to `false` in the `CachingAgentID` constructor.
|
|
67
71
|
|
|
68
72
|
Secondly, the UnetSocket API caches the responses to parameter requests for a limited time. If the user requests the same parameter again, the UnetSocket will return the cached response. The time to cache a response is set by the `cacheTime` property in the `CachingAgentID` constructor.
|
|
69
73
|
|
|
70
74
|
```js
|
|
71
|
-
import {UnetMessages,
|
|
72
|
-
let gw = new
|
|
73
|
-
let nodeinfo = await gw.agentForService(Services.NODE_INFO); // returns a CachingAgentID
|
|
75
|
+
import {UnetMessages, CachingGateway} from 'unetjs'
|
|
76
|
+
let gw = new CachingGateway({...});
|
|
77
|
+
let nodeinfo = await gw.agentForService(Services.NODE_INFO); // returns a CachingAgentID
|
|
74
78
|
let cLoc = nodeinfo.get('location'); // this will request all the Parameters from the Agent, and cache the responses.
|
|
75
79
|
...
|
|
76
80
|
cLoc = nodeinfo.get('location', maxage=5000); // this will return the cached response if it was called within 5000ms of the original request.
|
|
@@ -79,9 +83,9 @@ cLoc = nodeinfo.get('location', maxage=0); // this will force the Gateway to req
|
|
|
79
83
|
```
|
|
80
84
|
|
|
81
85
|
```js
|
|
82
|
-
import {UnetMessages,
|
|
83
|
-
let gw = new
|
|
84
|
-
let nodeinfo = await gw.agentForService(Services.NODE_INFO); // returns a CachingAgentID
|
|
86
|
+
import {UnetMessages, CachingGateway} from 'unetjs'
|
|
87
|
+
let gw = new CachingGateway({...});
|
|
88
|
+
let nodeinfo = await gw.agentForService(Services.NODE_INFO); // returns a CachingAgentID
|
|
85
89
|
let nonCachingNodeInfo = await gw.agentForService(Services.NODE_INFO, false); // returns an AgentID without caching (original fjage.js functionality).
|
|
86
90
|
let cLoc = nonCachingNodeInfo.get('location'); // this will request the `location` parameter from the Agent.
|
|
87
91
|
...
|
package/dist/cjs/unet.cjs
CHANGED
|
@@ -1,28 +1,8 @@
|
|
|
1
|
-
/* unet.js
|
|
1
|
+
/* unet.js v3.0.0 2023-12-11T11:03:52.183Z */
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function _interopNamespace(e) {
|
|
8
|
-
if (e && e.__esModule) return e;
|
|
9
|
-
var n = Object.create(null);
|
|
10
|
-
if (e) {
|
|
11
|
-
Object.keys(e).forEach(function (k) {
|
|
12
|
-
if (k !== 'default') {
|
|
13
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
-
enumerable: true,
|
|
16
|
-
get: function () { return e[k]; }
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
n["default"] = e;
|
|
22
|
-
return Object.freeze(n);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/* fjage.js v1.10.3 */
|
|
5
|
+
/* fjage.js v1.11.2 */
|
|
26
6
|
|
|
27
7
|
const isBrowser =
|
|
28
8
|
typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
@@ -47,10 +27,13 @@ const isJsDom =
|
|
|
47
27
|
(navigator.userAgent.includes("Node.js") ||
|
|
48
28
|
navigator.userAgent.includes("jsdom")));
|
|
49
29
|
|
|
50
|
-
typeof Deno !== "undefined" &&
|
|
30
|
+
typeof Deno !== "undefined" &&
|
|
31
|
+
typeof Deno.version !== "undefined" &&
|
|
32
|
+
typeof Deno.version.deno !== "undefined";
|
|
51
33
|
|
|
52
34
|
const SOCKET_OPEN = 'open';
|
|
53
35
|
const SOCKET_OPENING = 'opening';
|
|
36
|
+
const DEFAULT_RECONNECT_TIME$1 = 5000; // ms, delay between retries to connect to the server.
|
|
54
37
|
|
|
55
38
|
var createConnection;
|
|
56
39
|
|
|
@@ -62,17 +45,24 @@ class TCPconnector {
|
|
|
62
45
|
|
|
63
46
|
/**
|
|
64
47
|
* Create an TCPConnector to connect to a fjage master over TCP
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
48
|
+
* @param {Object} opts
|
|
49
|
+
* @param {string} [opts.hostname='localhost'] - hostname/ip address of the master container to connect to
|
|
50
|
+
* @param {number} opts.port - port number of the master container to connect to
|
|
51
|
+
* @param {string} opts.pathname - path of the master container to connect to
|
|
52
|
+
* @param {boolean} opts.keepAlive - try to reconnect if the connection is lost
|
|
53
|
+
* @param {number} [opts.reconnectTime=5000] - time before reconnection is attempted after an error
|
|
68
54
|
*/
|
|
69
55
|
constructor(opts = {}) {
|
|
70
56
|
this.url = new URL('tcp://localhost');
|
|
71
57
|
let host = opts.hostname || 'localhost';
|
|
72
58
|
let port = opts.port || -1;
|
|
73
|
-
this.url.hostname =
|
|
74
|
-
this.url.port =
|
|
59
|
+
this.url.hostname = host;
|
|
60
|
+
this.url.port = port;
|
|
75
61
|
this._buf = '';
|
|
62
|
+
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME$1;
|
|
63
|
+
this._keepAlive = opts.keepAlive || true;
|
|
64
|
+
this._firstConn = true; // if the Gateway has managed to connect to a server before
|
|
65
|
+
this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
|
|
76
66
|
this.pendingOnOpen = []; // list of callbacks make as soon as gateway is open
|
|
77
67
|
this.connListeners = []; // external listeners wanting to listen connection events
|
|
78
68
|
this._sockInit(host, port);
|
|
@@ -88,7 +78,7 @@ class TCPconnector {
|
|
|
88
78
|
_sockInit(host, port){
|
|
89
79
|
if (!createConnection){
|
|
90
80
|
try {
|
|
91
|
-
|
|
81
|
+
import('net').then(module => {
|
|
92
82
|
createConnection = module.createConnection;
|
|
93
83
|
this._sockSetup(host, port);
|
|
94
84
|
});
|
|
@@ -97,7 +87,7 @@ class TCPconnector {
|
|
|
97
87
|
}
|
|
98
88
|
}else {
|
|
99
89
|
this._sockSetup(host, port);
|
|
100
|
-
}
|
|
90
|
+
}
|
|
101
91
|
}
|
|
102
92
|
|
|
103
93
|
_sockSetup(host, port){
|
|
@@ -116,18 +106,18 @@ class TCPconnector {
|
|
|
116
106
|
}
|
|
117
107
|
|
|
118
108
|
_sockReconnect(){
|
|
119
|
-
if (this._firstConn || !this.
|
|
109
|
+
if (this._firstConn || !this._keepAlive || this.sock.readyState == SOCKET_OPENING || this.sock.readyState == SOCKET_OPEN) return;
|
|
120
110
|
if (this._firstReConn) this._sendConnEvent(false);
|
|
121
111
|
this._firstReConn = false;
|
|
122
|
-
if(this.debug) console.log('Reconnecting to ', this.sock.remoteAddress + ':' + this.sock.remotePort);
|
|
123
112
|
setTimeout(() => {
|
|
124
113
|
this.pendingOnOpen = [];
|
|
125
|
-
this._sockSetup(this.
|
|
114
|
+
this._sockSetup(this.url.hostname, this.url.port);
|
|
126
115
|
}, this._reconnectTime);
|
|
127
116
|
}
|
|
128
117
|
|
|
129
118
|
_onSockOpen() {
|
|
130
119
|
this._sendConnEvent(true);
|
|
120
|
+
this._firstConn = false;
|
|
131
121
|
this.sock.on('close', this._sockReconnect.bind(this));
|
|
132
122
|
this.sock.on('data', this._processSockData.bind(this));
|
|
133
123
|
this.pendingOnOpen.forEach(cb => cb());
|
|
@@ -184,7 +174,7 @@ class TCPconnector {
|
|
|
184
174
|
* @ignore
|
|
185
175
|
* @param {string} s - incoming message string
|
|
186
176
|
*/
|
|
187
|
-
|
|
177
|
+
|
|
188
178
|
/**
|
|
189
179
|
* Add listener for connection events
|
|
190
180
|
* @param {function} listener - a listener callback that is called when the connection is opened/closed
|
|
@@ -215,12 +205,16 @@ class TCPconnector {
|
|
|
215
205
|
if (this.sock.readyState == SOCKET_OPENING) {
|
|
216
206
|
this.pendingOnOpen.push(() => {
|
|
217
207
|
this.sock.send('{"alive": false}\n');
|
|
218
|
-
this.sock.
|
|
208
|
+
this.sock.removeAllListeners('connect');
|
|
209
|
+
this.sock.removeAllListeners('error');
|
|
210
|
+
this.sock.removeAllListeners('close');
|
|
219
211
|
this.sock.destroy();
|
|
220
212
|
});
|
|
221
213
|
} else if (this.sock.readyState == SOCKET_OPEN) {
|
|
222
214
|
this.sock.send('{"alive": false}\n');
|
|
223
|
-
this.sock.
|
|
215
|
+
this.sock.removeAllListeners('connect');
|
|
216
|
+
this.sock.removeAllListeners('error');
|
|
217
|
+
this.sock.removeAllListeners('close');
|
|
224
218
|
this.sock.destroy();
|
|
225
219
|
}
|
|
226
220
|
}
|
|
@@ -245,11 +239,11 @@ class WSConnector {
|
|
|
245
239
|
*/
|
|
246
240
|
constructor(opts = {}) {
|
|
247
241
|
this.url = new URL('ws://localhost');
|
|
248
|
-
this.url.hostname = opts.hostname;
|
|
242
|
+
this.url.hostname = opts.hostname;
|
|
249
243
|
this.url.port = opts.port;
|
|
250
244
|
this.url.pathname = opts.pathname;
|
|
251
245
|
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME;
|
|
252
|
-
this._keepAlive = opts.keepAlive;
|
|
246
|
+
this._keepAlive = opts.keepAlive || true;
|
|
253
247
|
this.debug = opts.debug || false; // debug info to be logged to console?
|
|
254
248
|
this._firstConn = true; // if the Gateway has managed to connect to a server before
|
|
255
249
|
this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
|
|
@@ -335,7 +329,7 @@ class WSConnector {
|
|
|
335
329
|
* @ignore
|
|
336
330
|
* @param {string} s - incoming message string
|
|
337
331
|
*/
|
|
338
|
-
|
|
332
|
+
|
|
339
333
|
/**
|
|
340
334
|
* Add listener for connection events
|
|
341
335
|
* @param {function} listener - a listener callback that is called when the connection is opened/closed
|
|
@@ -379,6 +373,7 @@ class WSConnector {
|
|
|
379
373
|
|
|
380
374
|
/* global global Buffer */
|
|
381
375
|
|
|
376
|
+
|
|
382
377
|
const DEFAULT_QUEUE_SIZE = 128; // max number of old unreceived messages to store
|
|
383
378
|
|
|
384
379
|
/**
|
|
@@ -706,7 +701,13 @@ class Gateway {
|
|
|
706
701
|
_sendEvent(type, val) {
|
|
707
702
|
if (Array.isArray(this.eventListeners[type])) {
|
|
708
703
|
this.eventListeners[type].forEach(l => {
|
|
709
|
-
l && {}.toString.call(l) === '[object Function]'
|
|
704
|
+
if (l && {}.toString.call(l) === '[object Function]'){
|
|
705
|
+
try {
|
|
706
|
+
l(val);
|
|
707
|
+
} catch (error) {
|
|
708
|
+
console.warn('Error in event listener : ' + error);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
710
711
|
});
|
|
711
712
|
}
|
|
712
713
|
}
|
|
@@ -735,18 +736,26 @@ class Gateway {
|
|
|
735
736
|
var consumed = false;
|
|
736
737
|
if (Array.isArray(this.eventListeners['message'])){
|
|
737
738
|
for (var i = 0; i < this.eventListeners['message'].length; i++) {
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
739
|
+
try {
|
|
740
|
+
if (this.eventListeners['message'][i](msg)) {
|
|
741
|
+
consumed = true;
|
|
742
|
+
break;
|
|
743
|
+
}
|
|
744
|
+
} catch (error) {
|
|
745
|
+
console.warn('Error in message listener : ' + error);
|
|
741
746
|
}
|
|
742
747
|
}
|
|
743
748
|
}
|
|
744
749
|
// iterate over internal callbacks, until one consumes the message
|
|
745
750
|
for (var key in this.listener){
|
|
746
751
|
// callback returns true if it has consumed the message
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
752
|
+
try {
|
|
753
|
+
if (this.listener[key](msg)) {
|
|
754
|
+
consumed = true;
|
|
755
|
+
break;
|
|
756
|
+
}
|
|
757
|
+
} catch (error) {
|
|
758
|
+
console.warn('Error in listener : ' + error);
|
|
750
759
|
}
|
|
751
760
|
}
|
|
752
761
|
if(!consumed) {
|
|
@@ -834,6 +843,7 @@ class Gateway {
|
|
|
834
843
|
this.connector.write('{"alive": true}');
|
|
835
844
|
this._update_watch();
|
|
836
845
|
}
|
|
846
|
+
this._sendEvent('conn', state);
|
|
837
847
|
});
|
|
838
848
|
return conn;
|
|
839
849
|
}
|
|
@@ -847,7 +857,12 @@ class Gateway {
|
|
|
847
857
|
} else if (filter.__proto__.name == 'Message' || filter.__proto__.__proto__.name == 'Message') {
|
|
848
858
|
return filter.__clazz__ == msg.__clazz__;
|
|
849
859
|
} else if (typeof filter == 'function') {
|
|
850
|
-
|
|
860
|
+
try {
|
|
861
|
+
return filter(msg);
|
|
862
|
+
}catch(e){
|
|
863
|
+
console.warn('Error in filter : ' + e);
|
|
864
|
+
return false;
|
|
865
|
+
}
|
|
851
866
|
} else {
|
|
852
867
|
return msg instanceof filter;
|
|
853
868
|
}
|
|
@@ -1117,7 +1132,7 @@ class Gateway {
|
|
|
1117
1132
|
let timer;
|
|
1118
1133
|
if (timeout > 0){
|
|
1119
1134
|
timer = setTimeout(() => {
|
|
1120
|
-
delete this.listener[lid];
|
|
1135
|
+
this.listener[lid] && delete this.listener[lid];
|
|
1121
1136
|
if (this.debug) console.log('Receive Timeout : ' + filter);
|
|
1122
1137
|
resolve();
|
|
1123
1138
|
}, timeout);
|
|
@@ -1125,7 +1140,7 @@ class Gateway {
|
|
|
1125
1140
|
this.listener[lid] = msg => {
|
|
1126
1141
|
if (!this._matchMessage(filter, msg)) return false;
|
|
1127
1142
|
if(timer) clearTimeout(timer);
|
|
1128
|
-
delete this.listener[lid];
|
|
1143
|
+
this.listener[lid] && delete this.listener[lid];
|
|
1129
1144
|
resolve(msg);
|
|
1130
1145
|
return true;
|
|
1131
1146
|
};
|
|
@@ -1305,7 +1320,8 @@ let UnetServices = {
|
|
|
1305
1320
|
'REMOTE': 'org.arl.unet.Services.REMOTE',
|
|
1306
1321
|
'STATE_MANAGER': 'org.arl.unet.Services.STATE_MANAGER',
|
|
1307
1322
|
'DEVICE_INFO': 'org.arl.unet.Services.DEVICE_INFO',
|
|
1308
|
-
'DOA': 'org.arl.unet.Services.DOA'
|
|
1323
|
+
'DOA': 'org.arl.unet.Services.DOA',
|
|
1324
|
+
'SCHEDULER':'org.arl.unet.Services.SCHEDULER'
|
|
1309
1325
|
};
|
|
1310
1326
|
|
|
1311
1327
|
Object.assign(Services, UnetServices);
|
|
@@ -1723,7 +1739,7 @@ class UnetSocket {
|
|
|
1723
1739
|
|
|
1724
1740
|
constructor(hostname, port, path='') {
|
|
1725
1741
|
return (async () => {
|
|
1726
|
-
this.gw = new
|
|
1742
|
+
this.gw = new Gateway({
|
|
1727
1743
|
hostname : hostname,
|
|
1728
1744
|
port : port,
|
|
1729
1745
|
path : path
|
|
@@ -1983,7 +1999,8 @@ class UnetSocket {
|
|
|
1983
1999
|
|
|
1984
2000
|
exports.AgentID = AgentID;
|
|
1985
2001
|
exports.CachingAgentID = CachingAgentID;
|
|
1986
|
-
exports.
|
|
2002
|
+
exports.CachingGateway = CachingGateway;
|
|
2003
|
+
exports.Gateway = Gateway;
|
|
1987
2004
|
exports.Message = Message;
|
|
1988
2005
|
exports.MessageClass = MessageClass;
|
|
1989
2006
|
exports.Performative = Performative;
|
package/dist/esm/unet.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/* unet.js
|
|
1
|
+
/* unet.js v3.0.0 2023-12-11T11:03:52.183Z */
|
|
2
2
|
|
|
3
|
-
/* fjage.js v1.
|
|
3
|
+
/* fjage.js v1.11.2 */
|
|
4
4
|
|
|
5
5
|
const isBrowser =
|
|
6
6
|
typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
@@ -25,10 +25,13 @@ const isJsDom =
|
|
|
25
25
|
(navigator.userAgent.includes("Node.js") ||
|
|
26
26
|
navigator.userAgent.includes("jsdom")));
|
|
27
27
|
|
|
28
|
-
typeof Deno !== "undefined" &&
|
|
28
|
+
typeof Deno !== "undefined" &&
|
|
29
|
+
typeof Deno.version !== "undefined" &&
|
|
30
|
+
typeof Deno.version.deno !== "undefined";
|
|
29
31
|
|
|
30
32
|
const SOCKET_OPEN = 'open';
|
|
31
33
|
const SOCKET_OPENING = 'opening';
|
|
34
|
+
const DEFAULT_RECONNECT_TIME$1 = 5000; // ms, delay between retries to connect to the server.
|
|
32
35
|
|
|
33
36
|
var createConnection;
|
|
34
37
|
|
|
@@ -40,17 +43,24 @@ class TCPconnector {
|
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
45
|
* Create an TCPConnector to connect to a fjage master over TCP
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
* @param {Object} opts
|
|
47
|
+
* @param {string} [opts.hostname='localhost'] - hostname/ip address of the master container to connect to
|
|
48
|
+
* @param {number} opts.port - port number of the master container to connect to
|
|
49
|
+
* @param {string} opts.pathname - path of the master container to connect to
|
|
50
|
+
* @param {boolean} opts.keepAlive - try to reconnect if the connection is lost
|
|
51
|
+
* @param {number} [opts.reconnectTime=5000] - time before reconnection is attempted after an error
|
|
46
52
|
*/
|
|
47
53
|
constructor(opts = {}) {
|
|
48
54
|
this.url = new URL('tcp://localhost');
|
|
49
55
|
let host = opts.hostname || 'localhost';
|
|
50
56
|
let port = opts.port || -1;
|
|
51
|
-
this.url.hostname =
|
|
52
|
-
this.url.port =
|
|
57
|
+
this.url.hostname = host;
|
|
58
|
+
this.url.port = port;
|
|
53
59
|
this._buf = '';
|
|
60
|
+
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME$1;
|
|
61
|
+
this._keepAlive = opts.keepAlive || true;
|
|
62
|
+
this._firstConn = true; // if the Gateway has managed to connect to a server before
|
|
63
|
+
this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
|
|
54
64
|
this.pendingOnOpen = []; // list of callbacks make as soon as gateway is open
|
|
55
65
|
this.connListeners = []; // external listeners wanting to listen connection events
|
|
56
66
|
this._sockInit(host, port);
|
|
@@ -75,7 +85,7 @@ class TCPconnector {
|
|
|
75
85
|
}
|
|
76
86
|
}else {
|
|
77
87
|
this._sockSetup(host, port);
|
|
78
|
-
}
|
|
88
|
+
}
|
|
79
89
|
}
|
|
80
90
|
|
|
81
91
|
_sockSetup(host, port){
|
|
@@ -94,18 +104,18 @@ class TCPconnector {
|
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
_sockReconnect(){
|
|
97
|
-
if (this._firstConn || !this.
|
|
107
|
+
if (this._firstConn || !this._keepAlive || this.sock.readyState == SOCKET_OPENING || this.sock.readyState == SOCKET_OPEN) return;
|
|
98
108
|
if (this._firstReConn) this._sendConnEvent(false);
|
|
99
109
|
this._firstReConn = false;
|
|
100
|
-
if(this.debug) console.log('Reconnecting to ', this.sock.remoteAddress + ':' + this.sock.remotePort);
|
|
101
110
|
setTimeout(() => {
|
|
102
111
|
this.pendingOnOpen = [];
|
|
103
|
-
this._sockSetup(this.
|
|
112
|
+
this._sockSetup(this.url.hostname, this.url.port);
|
|
104
113
|
}, this._reconnectTime);
|
|
105
114
|
}
|
|
106
115
|
|
|
107
116
|
_onSockOpen() {
|
|
108
117
|
this._sendConnEvent(true);
|
|
118
|
+
this._firstConn = false;
|
|
109
119
|
this.sock.on('close', this._sockReconnect.bind(this));
|
|
110
120
|
this.sock.on('data', this._processSockData.bind(this));
|
|
111
121
|
this.pendingOnOpen.forEach(cb => cb());
|
|
@@ -162,7 +172,7 @@ class TCPconnector {
|
|
|
162
172
|
* @ignore
|
|
163
173
|
* @param {string} s - incoming message string
|
|
164
174
|
*/
|
|
165
|
-
|
|
175
|
+
|
|
166
176
|
/**
|
|
167
177
|
* Add listener for connection events
|
|
168
178
|
* @param {function} listener - a listener callback that is called when the connection is opened/closed
|
|
@@ -193,12 +203,16 @@ class TCPconnector {
|
|
|
193
203
|
if (this.sock.readyState == SOCKET_OPENING) {
|
|
194
204
|
this.pendingOnOpen.push(() => {
|
|
195
205
|
this.sock.send('{"alive": false}\n');
|
|
196
|
-
this.sock.
|
|
206
|
+
this.sock.removeAllListeners('connect');
|
|
207
|
+
this.sock.removeAllListeners('error');
|
|
208
|
+
this.sock.removeAllListeners('close');
|
|
197
209
|
this.sock.destroy();
|
|
198
210
|
});
|
|
199
211
|
} else if (this.sock.readyState == SOCKET_OPEN) {
|
|
200
212
|
this.sock.send('{"alive": false}\n');
|
|
201
|
-
this.sock.
|
|
213
|
+
this.sock.removeAllListeners('connect');
|
|
214
|
+
this.sock.removeAllListeners('error');
|
|
215
|
+
this.sock.removeAllListeners('close');
|
|
202
216
|
this.sock.destroy();
|
|
203
217
|
}
|
|
204
218
|
}
|
|
@@ -223,11 +237,11 @@ class WSConnector {
|
|
|
223
237
|
*/
|
|
224
238
|
constructor(opts = {}) {
|
|
225
239
|
this.url = new URL('ws://localhost');
|
|
226
|
-
this.url.hostname = opts.hostname;
|
|
240
|
+
this.url.hostname = opts.hostname;
|
|
227
241
|
this.url.port = opts.port;
|
|
228
242
|
this.url.pathname = opts.pathname;
|
|
229
243
|
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME;
|
|
230
|
-
this._keepAlive = opts.keepAlive;
|
|
244
|
+
this._keepAlive = opts.keepAlive || true;
|
|
231
245
|
this.debug = opts.debug || false; // debug info to be logged to console?
|
|
232
246
|
this._firstConn = true; // if the Gateway has managed to connect to a server before
|
|
233
247
|
this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
|
|
@@ -313,7 +327,7 @@ class WSConnector {
|
|
|
313
327
|
* @ignore
|
|
314
328
|
* @param {string} s - incoming message string
|
|
315
329
|
*/
|
|
316
|
-
|
|
330
|
+
|
|
317
331
|
/**
|
|
318
332
|
* Add listener for connection events
|
|
319
333
|
* @param {function} listener - a listener callback that is called when the connection is opened/closed
|
|
@@ -357,6 +371,7 @@ class WSConnector {
|
|
|
357
371
|
|
|
358
372
|
/* global global Buffer */
|
|
359
373
|
|
|
374
|
+
|
|
360
375
|
const DEFAULT_QUEUE_SIZE = 128; // max number of old unreceived messages to store
|
|
361
376
|
|
|
362
377
|
/**
|
|
@@ -684,7 +699,13 @@ class Gateway {
|
|
|
684
699
|
_sendEvent(type, val) {
|
|
685
700
|
if (Array.isArray(this.eventListeners[type])) {
|
|
686
701
|
this.eventListeners[type].forEach(l => {
|
|
687
|
-
l && {}.toString.call(l) === '[object Function]'
|
|
702
|
+
if (l && {}.toString.call(l) === '[object Function]'){
|
|
703
|
+
try {
|
|
704
|
+
l(val);
|
|
705
|
+
} catch (error) {
|
|
706
|
+
console.warn('Error in event listener : ' + error);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
688
709
|
});
|
|
689
710
|
}
|
|
690
711
|
}
|
|
@@ -713,18 +734,26 @@ class Gateway {
|
|
|
713
734
|
var consumed = false;
|
|
714
735
|
if (Array.isArray(this.eventListeners['message'])){
|
|
715
736
|
for (var i = 0; i < this.eventListeners['message'].length; i++) {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
737
|
+
try {
|
|
738
|
+
if (this.eventListeners['message'][i](msg)) {
|
|
739
|
+
consumed = true;
|
|
740
|
+
break;
|
|
741
|
+
}
|
|
742
|
+
} catch (error) {
|
|
743
|
+
console.warn('Error in message listener : ' + error);
|
|
719
744
|
}
|
|
720
745
|
}
|
|
721
746
|
}
|
|
722
747
|
// iterate over internal callbacks, until one consumes the message
|
|
723
748
|
for (var key in this.listener){
|
|
724
749
|
// callback returns true if it has consumed the message
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
750
|
+
try {
|
|
751
|
+
if (this.listener[key](msg)) {
|
|
752
|
+
consumed = true;
|
|
753
|
+
break;
|
|
754
|
+
}
|
|
755
|
+
} catch (error) {
|
|
756
|
+
console.warn('Error in listener : ' + error);
|
|
728
757
|
}
|
|
729
758
|
}
|
|
730
759
|
if(!consumed) {
|
|
@@ -812,6 +841,7 @@ class Gateway {
|
|
|
812
841
|
this.connector.write('{"alive": true}');
|
|
813
842
|
this._update_watch();
|
|
814
843
|
}
|
|
844
|
+
this._sendEvent('conn', state);
|
|
815
845
|
});
|
|
816
846
|
return conn;
|
|
817
847
|
}
|
|
@@ -825,7 +855,12 @@ class Gateway {
|
|
|
825
855
|
} else if (filter.__proto__.name == 'Message' || filter.__proto__.__proto__.name == 'Message') {
|
|
826
856
|
return filter.__clazz__ == msg.__clazz__;
|
|
827
857
|
} else if (typeof filter == 'function') {
|
|
828
|
-
|
|
858
|
+
try {
|
|
859
|
+
return filter(msg);
|
|
860
|
+
}catch(e){
|
|
861
|
+
console.warn('Error in filter : ' + e);
|
|
862
|
+
return false;
|
|
863
|
+
}
|
|
829
864
|
} else {
|
|
830
865
|
return msg instanceof filter;
|
|
831
866
|
}
|
|
@@ -1095,7 +1130,7 @@ class Gateway {
|
|
|
1095
1130
|
let timer;
|
|
1096
1131
|
if (timeout > 0){
|
|
1097
1132
|
timer = setTimeout(() => {
|
|
1098
|
-
delete this.listener[lid];
|
|
1133
|
+
this.listener[lid] && delete this.listener[lid];
|
|
1099
1134
|
if (this.debug) console.log('Receive Timeout : ' + filter);
|
|
1100
1135
|
resolve();
|
|
1101
1136
|
}, timeout);
|
|
@@ -1103,7 +1138,7 @@ class Gateway {
|
|
|
1103
1138
|
this.listener[lid] = msg => {
|
|
1104
1139
|
if (!this._matchMessage(filter, msg)) return false;
|
|
1105
1140
|
if(timer) clearTimeout(timer);
|
|
1106
|
-
delete this.listener[lid];
|
|
1141
|
+
this.listener[lid] && delete this.listener[lid];
|
|
1107
1142
|
resolve(msg);
|
|
1108
1143
|
return true;
|
|
1109
1144
|
};
|
|
@@ -1283,7 +1318,8 @@ let UnetServices = {
|
|
|
1283
1318
|
'REMOTE': 'org.arl.unet.Services.REMOTE',
|
|
1284
1319
|
'STATE_MANAGER': 'org.arl.unet.Services.STATE_MANAGER',
|
|
1285
1320
|
'DEVICE_INFO': 'org.arl.unet.Services.DEVICE_INFO',
|
|
1286
|
-
'DOA': 'org.arl.unet.Services.DOA'
|
|
1321
|
+
'DOA': 'org.arl.unet.Services.DOA',
|
|
1322
|
+
'SCHEDULER':'org.arl.unet.Services.SCHEDULER'
|
|
1287
1323
|
};
|
|
1288
1324
|
|
|
1289
1325
|
Object.assign(Services, UnetServices);
|
|
@@ -1701,7 +1737,7 @@ class UnetSocket {
|
|
|
1701
1737
|
|
|
1702
1738
|
constructor(hostname, port, path='') {
|
|
1703
1739
|
return (async () => {
|
|
1704
|
-
this.gw = new
|
|
1740
|
+
this.gw = new Gateway({
|
|
1705
1741
|
hostname : hostname,
|
|
1706
1742
|
port : port,
|
|
1707
1743
|
path : path
|
|
@@ -1959,4 +1995,4 @@ class UnetSocket {
|
|
|
1959
1995
|
}
|
|
1960
1996
|
}
|
|
1961
1997
|
|
|
1962
|
-
export { AgentID, CachingAgentID, CachingGateway
|
|
1998
|
+
export { AgentID, CachingAgentID, CachingGateway, Gateway, Message, MessageClass, Performative, Protocol, Services, UnetMessages, UnetSocket, toGps, toLocal };
|