unetjs 3.0.0 → 3.1.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/dist/cjs/unet.cjs +89 -39
- package/dist/esm/unet.js +89 -39
- package/dist/unetjs.js +88 -38
- 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 +2 -2
package/dist/cjs/unet.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/* unet.js v3.
|
|
1
|
+
/* unet.js v3.1.2 2024-02-21T08:15:43.663Z */
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
/* fjage.js v1.
|
|
5
|
+
/* fjage.js v1.12.1 */
|
|
6
6
|
|
|
7
7
|
const isBrowser =
|
|
8
8
|
typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
@@ -46,21 +46,20 @@ class TCPconnector {
|
|
|
46
46
|
/**
|
|
47
47
|
* Create an TCPConnector to connect to a fjage master over TCP
|
|
48
48
|
* @param {Object} opts
|
|
49
|
-
* @param {string}
|
|
50
|
-
* @param {
|
|
51
|
-
* @param {string} opts.pathname - path of the master container to connect to
|
|
49
|
+
* @param {string} opts.hostname - hostname/ip address of the master container to connect to
|
|
50
|
+
* @param {string} opts.port - port number of the master container to connect to
|
|
52
51
|
* @param {boolean} opts.keepAlive - try to reconnect if the connection is lost
|
|
53
52
|
* @param {number} [opts.reconnectTime=5000] - time before reconnection is attempted after an error
|
|
54
53
|
*/
|
|
55
54
|
constructor(opts = {}) {
|
|
55
|
+
let host = opts.hostname;
|
|
56
|
+
let port = opts.port;
|
|
57
|
+
this._keepAlive = opts.keepAlive;
|
|
58
|
+
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME$1;
|
|
56
59
|
this.url = new URL('tcp://localhost');
|
|
57
|
-
let host = opts.hostname || 'localhost';
|
|
58
|
-
let port = opts.port || -1;
|
|
59
60
|
this.url.hostname = host;
|
|
60
61
|
this.url.port = port;
|
|
61
62
|
this._buf = '';
|
|
62
|
-
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME$1;
|
|
63
|
-
this._keepAlive = opts.keepAlive || true;
|
|
64
63
|
this._firstConn = true; // if the Gateway has managed to connect to a server before
|
|
65
64
|
this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
|
|
66
65
|
this.pendingOnOpen = []; // list of callbacks make as soon as gateway is open
|
|
@@ -232,7 +231,7 @@ class WSConnector {
|
|
|
232
231
|
* Create an WSConnector to connect to a fjage master over WebSockets
|
|
233
232
|
* @param {Object} opts
|
|
234
233
|
* @param {string} opts.hostname - hostname/ip address of the master container to connect to
|
|
235
|
-
* @param {
|
|
234
|
+
* @param {string} opts.port - port number of the master container to connect to
|
|
236
235
|
* @param {string} opts.pathname - path of the master container to connect to
|
|
237
236
|
* @param {boolean} opts.keepAlive - try to reconnect if the connection is lost
|
|
238
237
|
* @param {number} [opts.reconnectTime=5000] - time before reconnection is attempted after an error
|
|
@@ -242,8 +241,8 @@ class WSConnector {
|
|
|
242
241
|
this.url.hostname = opts.hostname;
|
|
243
242
|
this.url.port = opts.port;
|
|
244
243
|
this.url.pathname = opts.pathname;
|
|
244
|
+
this._keepAlive = opts.keepAlive;
|
|
245
245
|
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME;
|
|
246
|
-
this._keepAlive = opts.keepAlive || true;
|
|
247
246
|
this.debug = opts.debug || false; // debug info to be logged to console?
|
|
248
247
|
this._firstConn = true; // if the Gateway has managed to connect to a server before
|
|
249
248
|
this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
|
|
@@ -502,14 +501,17 @@ class AgentID {
|
|
|
502
501
|
msg.index = Number.isInteger(index) ? index : -1;
|
|
503
502
|
const rsp = await this.owner.request(msg, timeout);
|
|
504
503
|
var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
|
|
505
|
-
if (!rsp || rsp.perf != Performative.INFORM || !rsp.param)
|
|
504
|
+
if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
|
|
505
|
+
if (this.owner._returnNullOnFailedResponse) return ret;
|
|
506
|
+
else throw new Error(`Unable to set ${this.name}.${params} to ${values}`);
|
|
507
|
+
}
|
|
506
508
|
if (Array.isArray(params)) {
|
|
507
509
|
if (!rsp.values) rsp.values = {};
|
|
508
510
|
if (rsp.param) rsp.values[rsp.param] = rsp.value;
|
|
509
511
|
const rvals = Object.keys(rsp.values);
|
|
510
512
|
return params.map( p => {
|
|
511
513
|
let f = rvals.find(rv => rv.endsWith(p));
|
|
512
|
-
return f ? rsp.values[f] :
|
|
514
|
+
return f ? rsp.values[f] : undefined;
|
|
513
515
|
});
|
|
514
516
|
} else {
|
|
515
517
|
return rsp.value;
|
|
@@ -540,7 +542,10 @@ class AgentID {
|
|
|
540
542
|
msg.index = Number.isInteger(index) ? index : -1;
|
|
541
543
|
const rsp = await this.owner.request(msg, timeout);
|
|
542
544
|
var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
|
|
543
|
-
if (!rsp || rsp.perf != Performative.INFORM ||
|
|
545
|
+
if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
|
|
546
|
+
if (this.owner._returnNullOnFailedResponse) return ret;
|
|
547
|
+
else throw new Error(`Unable to get ${this.name}.${params}`);
|
|
548
|
+
}
|
|
544
549
|
// Request for listing of all parameters.
|
|
545
550
|
if (!params) {
|
|
546
551
|
if (!rsp.values) rsp.values = {};
|
|
@@ -552,7 +557,7 @@ class AgentID {
|
|
|
552
557
|
const rvals = Object.keys(rsp.values);
|
|
553
558
|
return params.map(p => {
|
|
554
559
|
let f = rvals.find(rv => rv.endsWith(p));
|
|
555
|
-
return f ? rsp.values[f] :
|
|
560
|
+
return f ? rsp.values[f] : undefined;
|
|
556
561
|
});
|
|
557
562
|
} else {
|
|
558
563
|
return rsp.value;
|
|
@@ -636,12 +641,17 @@ class Message {
|
|
|
636
641
|
return null;
|
|
637
642
|
}
|
|
638
643
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
644
|
+
try {
|
|
645
|
+
let qclazz = obj.clazz;
|
|
646
|
+
let clazz = qclazz.replace(/^.*\./, '');
|
|
647
|
+
let rv = MessageClass[clazz] ? new MessageClass[clazz] : new Message();
|
|
648
|
+
rv.__clazz__ = qclazz;
|
|
649
|
+
rv._inflate(obj.data);
|
|
650
|
+
return rv;
|
|
651
|
+
} catch (err) {
|
|
652
|
+
console.warn('Error trying to deserialize JSON object : ', obj, err);
|
|
653
|
+
return null;
|
|
654
|
+
}
|
|
645
655
|
}
|
|
646
656
|
}
|
|
647
657
|
|
|
@@ -652,16 +662,17 @@ class Message {
|
|
|
652
662
|
*
|
|
653
663
|
* @class
|
|
654
664
|
* @param {Object} opts
|
|
655
|
-
* @param {string}
|
|
656
|
-
* @param {
|
|
657
|
-
* @param {string}
|
|
658
|
-
* @param {
|
|
659
|
-
* @param {number}
|
|
660
|
-
* @param {number}
|
|
661
|
-
* @param {
|
|
662
|
-
* @param {
|
|
663
|
-
* @param {
|
|
664
|
-
* @param {
|
|
665
|
+
* @param {string} [opts.hostname="localhost"] - hostname/ip address of the master container to connect to
|
|
666
|
+
* @param {string} [opts.port='1100'] - port number of the master container to connect to
|
|
667
|
+
* @param {string} [opts.pathname=""] - path of the master container to connect to (for WebSockets)
|
|
668
|
+
* @param {boolean} [opts.keepAlive=true] - try to reconnect if the connection is lost
|
|
669
|
+
* @param {number} [opts.queueSize=128] - size of the queue of received messages that haven't been consumed yet
|
|
670
|
+
* @param {number} [opts.timeout=1000] - timeout for fjage level messages in ms
|
|
671
|
+
* @param {boolean} [opts.returnNullOnFailedResponse=true] - return null instead of throwing an error when a parameter is not found
|
|
672
|
+
* @param {string} [hostname="localhost"] - <strike>Deprecated : hostname/ip address of the master container to connect to</strike>
|
|
673
|
+
* @param {number} [port=] - <strike>Deprecated : port number of the master container to connect to</strike>
|
|
674
|
+
* @param {string} [pathname=="/ws/"] - <strike>Deprecated : path of the master container to connect to (for WebSockets)</strike>
|
|
675
|
+
* @param {number} [timeout=1000] - <strike>Deprecated : timeout for fjage level messages in ms</strike>
|
|
665
676
|
*/
|
|
666
677
|
class Gateway {
|
|
667
678
|
|
|
@@ -670,13 +681,17 @@ class Gateway {
|
|
|
670
681
|
if (typeof opts === 'string' || opts instanceof String){
|
|
671
682
|
opts = {
|
|
672
683
|
'hostname': opts,
|
|
673
|
-
'port' : port
|
|
684
|
+
'port' : port,
|
|
674
685
|
'pathname' : pathname,
|
|
675
686
|
'timeout' : timeout
|
|
676
687
|
};
|
|
677
688
|
console.warn('Deprecated use of Gateway constructor');
|
|
678
689
|
}
|
|
679
|
-
|
|
690
|
+
|
|
691
|
+
// Set defaults
|
|
692
|
+
for (var key in GATEWAY_DEFAULTS){
|
|
693
|
+
if (opts[key] == undefined || opts[key] === '') opts[key] = GATEWAY_DEFAULTS[key];
|
|
694
|
+
}
|
|
680
695
|
var url = DEFAULT_URL;
|
|
681
696
|
url.hostname = opts.hostname;
|
|
682
697
|
url.port = opts.port;
|
|
@@ -685,7 +700,8 @@ class Gateway {
|
|
|
685
700
|
if (existing) return existing;
|
|
686
701
|
this._timeout = opts.timeout; // timeout for fjage level messages (agentForService etc)
|
|
687
702
|
this._keepAlive = opts.keepAlive; // reconnect if connection gets closed/errored
|
|
688
|
-
this._queueSize = opts.queueSize;
|
|
703
|
+
this._queueSize = opts.queueSize; // size of queue
|
|
704
|
+
this._returnNullOnFailedResponse = opts.returnNullOnFailedResponse; // null or error
|
|
689
705
|
this.pending = {}; // msgid to callback mapping for pending requests to server
|
|
690
706
|
this.subscriptions = {}; // hashset for all topics that are subscribed
|
|
691
707
|
this.listener = {}; // set of callbacks that want to listen to incoming messages
|
|
@@ -1036,6 +1052,30 @@ class Gateway {
|
|
|
1036
1052
|
this._update_watch();
|
|
1037
1053
|
}
|
|
1038
1054
|
|
|
1055
|
+
/**
|
|
1056
|
+
* Gets a list of all agents in the container.
|
|
1057
|
+
* @returns {Promise<AgentID[]>} - a promise which returns an array of all agent ids when resolved
|
|
1058
|
+
*/
|
|
1059
|
+
async agents() {
|
|
1060
|
+
let rq = { action: 'agents' };
|
|
1061
|
+
let rsp = await this._msgTxRx(rq);
|
|
1062
|
+
if (!rsp || !Array.isArray(rsp.agentIDs)) throw new Error('Unable to get agents');
|
|
1063
|
+
return rsp.agentIDs.map(aid => new AgentID(aid, false, this));
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* Check if an agent with a given name exists in the container.
|
|
1068
|
+
*
|
|
1069
|
+
* @param {AgentID|String} agentID - the agent id to check
|
|
1070
|
+
* @returns {Promise<boolean>} - a promise which returns true if the agent exists when resolved
|
|
1071
|
+
*/
|
|
1072
|
+
async containsAgent(agentID) {
|
|
1073
|
+
let rq = { action: 'containsAgent', agentID: agentID instanceof AgentID ? agentID.getName() : agentID };
|
|
1074
|
+
let rsp = await this._msgTxRx(rq);
|
|
1075
|
+
if (!rsp) throw new Error('Unable to check if agent exists');
|
|
1076
|
+
return !!rsp.answer;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1039
1079
|
/**
|
|
1040
1080
|
* Finds an agent that provides a named service. If multiple agents are registered
|
|
1041
1081
|
* to provide a given service, any of the agents' id may be returned.
|
|
@@ -1046,7 +1086,11 @@ class Gateway {
|
|
|
1046
1086
|
async agentForService(service) {
|
|
1047
1087
|
let rq = { action: 'agentForService', service: service };
|
|
1048
1088
|
let rsp = await this._msgTxRx(rq);
|
|
1049
|
-
if (!rsp
|
|
1089
|
+
if (!rsp) {
|
|
1090
|
+
if (this._returnNullOnFailedResponse) return null;
|
|
1091
|
+
else throw new Error('Unable to get agent for service');
|
|
1092
|
+
}
|
|
1093
|
+
if (!rsp.agentID) return null;
|
|
1050
1094
|
return new AgentID(rsp.agentID, false, this);
|
|
1051
1095
|
}
|
|
1052
1096
|
|
|
@@ -1060,7 +1104,11 @@ class Gateway {
|
|
|
1060
1104
|
let rq = { action: 'agentsForService', service: service };
|
|
1061
1105
|
let rsp = await this._msgTxRx(rq);
|
|
1062
1106
|
let aids = [];
|
|
1063
|
-
if (!rsp
|
|
1107
|
+
if (!rsp) {
|
|
1108
|
+
if (this._returnNullOnFailedResponse) return aids;
|
|
1109
|
+
else throw new Error('Unable to get agents for service');
|
|
1110
|
+
}
|
|
1111
|
+
if (!Array.isArray(rsp.agentIDs)) return aids;
|
|
1064
1112
|
for (var i = 0; i < rsp.agentIDs.length; i++)
|
|
1065
1113
|
aids.push(new AgentID(rsp.agentIDs[i], false, this));
|
|
1066
1114
|
return aids;
|
|
@@ -1279,7 +1327,8 @@ if (isBrowser || isWebWorker){
|
|
|
1279
1327
|
'pathname' : '/ws/',
|
|
1280
1328
|
'timeout': 1000,
|
|
1281
1329
|
'keepAlive' : true,
|
|
1282
|
-
'queueSize': DEFAULT_QUEUE_SIZE
|
|
1330
|
+
'queueSize': DEFAULT_QUEUE_SIZE,
|
|
1331
|
+
'returnNullOnFailedResponse': true
|
|
1283
1332
|
});
|
|
1284
1333
|
DEFAULT_URL = new URL('ws://localhost');
|
|
1285
1334
|
// Enable caching of Gateways
|
|
@@ -1293,7 +1342,8 @@ if (isBrowser || isWebWorker){
|
|
|
1293
1342
|
'pathname': '',
|
|
1294
1343
|
'timeout': 1000,
|
|
1295
1344
|
'keepAlive' : true,
|
|
1296
|
-
'queueSize': DEFAULT_QUEUE_SIZE
|
|
1345
|
+
'queueSize': DEFAULT_QUEUE_SIZE,
|
|
1346
|
+
'returnNullOnFailedResponse': true
|
|
1297
1347
|
});
|
|
1298
1348
|
DEFAULT_URL = new URL('tcp://localhost');
|
|
1299
1349
|
gObj.atob = a => Buffer.from(a, 'base64').toString('binary');
|
|
@@ -1728,7 +1778,7 @@ const RxFrameNtf = UnetMessages.RxFrameNtf;
|
|
|
1728
1778
|
*
|
|
1729
1779
|
* @class UnetSocket
|
|
1730
1780
|
* @param {string} [hostname] - hostname/ip address of the master container to connect to
|
|
1731
|
-
* @param {
|
|
1781
|
+
* @param {string} [port] - port number of the master container to connect to
|
|
1732
1782
|
* @param {string} [path=''] - path of the master container to connect to (for WebSockets)
|
|
1733
1783
|
* @returns {Promise<UnetSocket>} - Promise which resolves to the UnetSocket object being constructed
|
|
1734
1784
|
*
|
package/dist/esm/unet.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/* unet.js v3.
|
|
1
|
+
/* unet.js v3.1.2 2024-02-21T08:15:43.662Z */
|
|
2
2
|
|
|
3
|
-
/* fjage.js v1.
|
|
3
|
+
/* fjage.js v1.12.1 */
|
|
4
4
|
|
|
5
5
|
const isBrowser =
|
|
6
6
|
typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
@@ -44,21 +44,20 @@ class TCPconnector {
|
|
|
44
44
|
/**
|
|
45
45
|
* Create an TCPConnector to connect to a fjage master over TCP
|
|
46
46
|
* @param {Object} opts
|
|
47
|
-
* @param {string}
|
|
48
|
-
* @param {
|
|
49
|
-
* @param {string} opts.pathname - path of the master container to connect to
|
|
47
|
+
* @param {string} opts.hostname - hostname/ip address of the master container to connect to
|
|
48
|
+
* @param {string} opts.port - port number of the master container to connect to
|
|
50
49
|
* @param {boolean} opts.keepAlive - try to reconnect if the connection is lost
|
|
51
50
|
* @param {number} [opts.reconnectTime=5000] - time before reconnection is attempted after an error
|
|
52
51
|
*/
|
|
53
52
|
constructor(opts = {}) {
|
|
53
|
+
let host = opts.hostname;
|
|
54
|
+
let port = opts.port;
|
|
55
|
+
this._keepAlive = opts.keepAlive;
|
|
56
|
+
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME$1;
|
|
54
57
|
this.url = new URL('tcp://localhost');
|
|
55
|
-
let host = opts.hostname || 'localhost';
|
|
56
|
-
let port = opts.port || -1;
|
|
57
58
|
this.url.hostname = host;
|
|
58
59
|
this.url.port = port;
|
|
59
60
|
this._buf = '';
|
|
60
|
-
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME$1;
|
|
61
|
-
this._keepAlive = opts.keepAlive || true;
|
|
62
61
|
this._firstConn = true; // if the Gateway has managed to connect to a server before
|
|
63
62
|
this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
|
|
64
63
|
this.pendingOnOpen = []; // list of callbacks make as soon as gateway is open
|
|
@@ -230,7 +229,7 @@ class WSConnector {
|
|
|
230
229
|
* Create an WSConnector to connect to a fjage master over WebSockets
|
|
231
230
|
* @param {Object} opts
|
|
232
231
|
* @param {string} opts.hostname - hostname/ip address of the master container to connect to
|
|
233
|
-
* @param {
|
|
232
|
+
* @param {string} opts.port - port number of the master container to connect to
|
|
234
233
|
* @param {string} opts.pathname - path of the master container to connect to
|
|
235
234
|
* @param {boolean} opts.keepAlive - try to reconnect if the connection is lost
|
|
236
235
|
* @param {number} [opts.reconnectTime=5000] - time before reconnection is attempted after an error
|
|
@@ -240,8 +239,8 @@ class WSConnector {
|
|
|
240
239
|
this.url.hostname = opts.hostname;
|
|
241
240
|
this.url.port = opts.port;
|
|
242
241
|
this.url.pathname = opts.pathname;
|
|
242
|
+
this._keepAlive = opts.keepAlive;
|
|
243
243
|
this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME;
|
|
244
|
-
this._keepAlive = opts.keepAlive || true;
|
|
245
244
|
this.debug = opts.debug || false; // debug info to be logged to console?
|
|
246
245
|
this._firstConn = true; // if the Gateway has managed to connect to a server before
|
|
247
246
|
this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
|
|
@@ -500,14 +499,17 @@ class AgentID {
|
|
|
500
499
|
msg.index = Number.isInteger(index) ? index : -1;
|
|
501
500
|
const rsp = await this.owner.request(msg, timeout);
|
|
502
501
|
var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
|
|
503
|
-
if (!rsp || rsp.perf != Performative.INFORM || !rsp.param)
|
|
502
|
+
if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
|
|
503
|
+
if (this.owner._returnNullOnFailedResponse) return ret;
|
|
504
|
+
else throw new Error(`Unable to set ${this.name}.${params} to ${values}`);
|
|
505
|
+
}
|
|
504
506
|
if (Array.isArray(params)) {
|
|
505
507
|
if (!rsp.values) rsp.values = {};
|
|
506
508
|
if (rsp.param) rsp.values[rsp.param] = rsp.value;
|
|
507
509
|
const rvals = Object.keys(rsp.values);
|
|
508
510
|
return params.map( p => {
|
|
509
511
|
let f = rvals.find(rv => rv.endsWith(p));
|
|
510
|
-
return f ? rsp.values[f] :
|
|
512
|
+
return f ? rsp.values[f] : undefined;
|
|
511
513
|
});
|
|
512
514
|
} else {
|
|
513
515
|
return rsp.value;
|
|
@@ -538,7 +540,10 @@ class AgentID {
|
|
|
538
540
|
msg.index = Number.isInteger(index) ? index : -1;
|
|
539
541
|
const rsp = await this.owner.request(msg, timeout);
|
|
540
542
|
var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
|
|
541
|
-
if (!rsp || rsp.perf != Performative.INFORM ||
|
|
543
|
+
if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
|
|
544
|
+
if (this.owner._returnNullOnFailedResponse) return ret;
|
|
545
|
+
else throw new Error(`Unable to get ${this.name}.${params}`);
|
|
546
|
+
}
|
|
542
547
|
// Request for listing of all parameters.
|
|
543
548
|
if (!params) {
|
|
544
549
|
if (!rsp.values) rsp.values = {};
|
|
@@ -550,7 +555,7 @@ class AgentID {
|
|
|
550
555
|
const rvals = Object.keys(rsp.values);
|
|
551
556
|
return params.map(p => {
|
|
552
557
|
let f = rvals.find(rv => rv.endsWith(p));
|
|
553
|
-
return f ? rsp.values[f] :
|
|
558
|
+
return f ? rsp.values[f] : undefined;
|
|
554
559
|
});
|
|
555
560
|
} else {
|
|
556
561
|
return rsp.value;
|
|
@@ -634,12 +639,17 @@ class Message {
|
|
|
634
639
|
return null;
|
|
635
640
|
}
|
|
636
641
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
642
|
+
try {
|
|
643
|
+
let qclazz = obj.clazz;
|
|
644
|
+
let clazz = qclazz.replace(/^.*\./, '');
|
|
645
|
+
let rv = MessageClass[clazz] ? new MessageClass[clazz] : new Message();
|
|
646
|
+
rv.__clazz__ = qclazz;
|
|
647
|
+
rv._inflate(obj.data);
|
|
648
|
+
return rv;
|
|
649
|
+
} catch (err) {
|
|
650
|
+
console.warn('Error trying to deserialize JSON object : ', obj, err);
|
|
651
|
+
return null;
|
|
652
|
+
}
|
|
643
653
|
}
|
|
644
654
|
}
|
|
645
655
|
|
|
@@ -650,16 +660,17 @@ class Message {
|
|
|
650
660
|
*
|
|
651
661
|
* @class
|
|
652
662
|
* @param {Object} opts
|
|
653
|
-
* @param {string}
|
|
654
|
-
* @param {
|
|
655
|
-
* @param {string}
|
|
656
|
-
* @param {
|
|
657
|
-
* @param {number}
|
|
658
|
-
* @param {number}
|
|
659
|
-
* @param {
|
|
660
|
-
* @param {
|
|
661
|
-
* @param {
|
|
662
|
-
* @param {
|
|
663
|
+
* @param {string} [opts.hostname="localhost"] - hostname/ip address of the master container to connect to
|
|
664
|
+
* @param {string} [opts.port='1100'] - port number of the master container to connect to
|
|
665
|
+
* @param {string} [opts.pathname=""] - path of the master container to connect to (for WebSockets)
|
|
666
|
+
* @param {boolean} [opts.keepAlive=true] - try to reconnect if the connection is lost
|
|
667
|
+
* @param {number} [opts.queueSize=128] - size of the queue of received messages that haven't been consumed yet
|
|
668
|
+
* @param {number} [opts.timeout=1000] - timeout for fjage level messages in ms
|
|
669
|
+
* @param {boolean} [opts.returnNullOnFailedResponse=true] - return null instead of throwing an error when a parameter is not found
|
|
670
|
+
* @param {string} [hostname="localhost"] - <strike>Deprecated : hostname/ip address of the master container to connect to</strike>
|
|
671
|
+
* @param {number} [port=] - <strike>Deprecated : port number of the master container to connect to</strike>
|
|
672
|
+
* @param {string} [pathname=="/ws/"] - <strike>Deprecated : path of the master container to connect to (for WebSockets)</strike>
|
|
673
|
+
* @param {number} [timeout=1000] - <strike>Deprecated : timeout for fjage level messages in ms</strike>
|
|
663
674
|
*/
|
|
664
675
|
class Gateway {
|
|
665
676
|
|
|
@@ -668,13 +679,17 @@ class Gateway {
|
|
|
668
679
|
if (typeof opts === 'string' || opts instanceof String){
|
|
669
680
|
opts = {
|
|
670
681
|
'hostname': opts,
|
|
671
|
-
'port' : port
|
|
682
|
+
'port' : port,
|
|
672
683
|
'pathname' : pathname,
|
|
673
684
|
'timeout' : timeout
|
|
674
685
|
};
|
|
675
686
|
console.warn('Deprecated use of Gateway constructor');
|
|
676
687
|
}
|
|
677
|
-
|
|
688
|
+
|
|
689
|
+
// Set defaults
|
|
690
|
+
for (var key in GATEWAY_DEFAULTS){
|
|
691
|
+
if (opts[key] == undefined || opts[key] === '') opts[key] = GATEWAY_DEFAULTS[key];
|
|
692
|
+
}
|
|
678
693
|
var url = DEFAULT_URL;
|
|
679
694
|
url.hostname = opts.hostname;
|
|
680
695
|
url.port = opts.port;
|
|
@@ -683,7 +698,8 @@ class Gateway {
|
|
|
683
698
|
if (existing) return existing;
|
|
684
699
|
this._timeout = opts.timeout; // timeout for fjage level messages (agentForService etc)
|
|
685
700
|
this._keepAlive = opts.keepAlive; // reconnect if connection gets closed/errored
|
|
686
|
-
this._queueSize = opts.queueSize;
|
|
701
|
+
this._queueSize = opts.queueSize; // size of queue
|
|
702
|
+
this._returnNullOnFailedResponse = opts.returnNullOnFailedResponse; // null or error
|
|
687
703
|
this.pending = {}; // msgid to callback mapping for pending requests to server
|
|
688
704
|
this.subscriptions = {}; // hashset for all topics that are subscribed
|
|
689
705
|
this.listener = {}; // set of callbacks that want to listen to incoming messages
|
|
@@ -1034,6 +1050,30 @@ class Gateway {
|
|
|
1034
1050
|
this._update_watch();
|
|
1035
1051
|
}
|
|
1036
1052
|
|
|
1053
|
+
/**
|
|
1054
|
+
* Gets a list of all agents in the container.
|
|
1055
|
+
* @returns {Promise<AgentID[]>} - a promise which returns an array of all agent ids when resolved
|
|
1056
|
+
*/
|
|
1057
|
+
async agents() {
|
|
1058
|
+
let rq = { action: 'agents' };
|
|
1059
|
+
let rsp = await this._msgTxRx(rq);
|
|
1060
|
+
if (!rsp || !Array.isArray(rsp.agentIDs)) throw new Error('Unable to get agents');
|
|
1061
|
+
return rsp.agentIDs.map(aid => new AgentID(aid, false, this));
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
/**
|
|
1065
|
+
* Check if an agent with a given name exists in the container.
|
|
1066
|
+
*
|
|
1067
|
+
* @param {AgentID|String} agentID - the agent id to check
|
|
1068
|
+
* @returns {Promise<boolean>} - a promise which returns true if the agent exists when resolved
|
|
1069
|
+
*/
|
|
1070
|
+
async containsAgent(agentID) {
|
|
1071
|
+
let rq = { action: 'containsAgent', agentID: agentID instanceof AgentID ? agentID.getName() : agentID };
|
|
1072
|
+
let rsp = await this._msgTxRx(rq);
|
|
1073
|
+
if (!rsp) throw new Error('Unable to check if agent exists');
|
|
1074
|
+
return !!rsp.answer;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1037
1077
|
/**
|
|
1038
1078
|
* Finds an agent that provides a named service. If multiple agents are registered
|
|
1039
1079
|
* to provide a given service, any of the agents' id may be returned.
|
|
@@ -1044,7 +1084,11 @@ class Gateway {
|
|
|
1044
1084
|
async agentForService(service) {
|
|
1045
1085
|
let rq = { action: 'agentForService', service: service };
|
|
1046
1086
|
let rsp = await this._msgTxRx(rq);
|
|
1047
|
-
if (!rsp
|
|
1087
|
+
if (!rsp) {
|
|
1088
|
+
if (this._returnNullOnFailedResponse) return null;
|
|
1089
|
+
else throw new Error('Unable to get agent for service');
|
|
1090
|
+
}
|
|
1091
|
+
if (!rsp.agentID) return null;
|
|
1048
1092
|
return new AgentID(rsp.agentID, false, this);
|
|
1049
1093
|
}
|
|
1050
1094
|
|
|
@@ -1058,7 +1102,11 @@ class Gateway {
|
|
|
1058
1102
|
let rq = { action: 'agentsForService', service: service };
|
|
1059
1103
|
let rsp = await this._msgTxRx(rq);
|
|
1060
1104
|
let aids = [];
|
|
1061
|
-
if (!rsp
|
|
1105
|
+
if (!rsp) {
|
|
1106
|
+
if (this._returnNullOnFailedResponse) return aids;
|
|
1107
|
+
else throw new Error('Unable to get agents for service');
|
|
1108
|
+
}
|
|
1109
|
+
if (!Array.isArray(rsp.agentIDs)) return aids;
|
|
1062
1110
|
for (var i = 0; i < rsp.agentIDs.length; i++)
|
|
1063
1111
|
aids.push(new AgentID(rsp.agentIDs[i], false, this));
|
|
1064
1112
|
return aids;
|
|
@@ -1277,7 +1325,8 @@ if (isBrowser || isWebWorker){
|
|
|
1277
1325
|
'pathname' : '/ws/',
|
|
1278
1326
|
'timeout': 1000,
|
|
1279
1327
|
'keepAlive' : true,
|
|
1280
|
-
'queueSize': DEFAULT_QUEUE_SIZE
|
|
1328
|
+
'queueSize': DEFAULT_QUEUE_SIZE,
|
|
1329
|
+
'returnNullOnFailedResponse': true
|
|
1281
1330
|
});
|
|
1282
1331
|
DEFAULT_URL = new URL('ws://localhost');
|
|
1283
1332
|
// Enable caching of Gateways
|
|
@@ -1291,7 +1340,8 @@ if (isBrowser || isWebWorker){
|
|
|
1291
1340
|
'pathname': '',
|
|
1292
1341
|
'timeout': 1000,
|
|
1293
1342
|
'keepAlive' : true,
|
|
1294
|
-
'queueSize': DEFAULT_QUEUE_SIZE
|
|
1343
|
+
'queueSize': DEFAULT_QUEUE_SIZE,
|
|
1344
|
+
'returnNullOnFailedResponse': true
|
|
1295
1345
|
});
|
|
1296
1346
|
DEFAULT_URL = new URL('tcp://localhost');
|
|
1297
1347
|
gObj.atob = a => Buffer.from(a, 'base64').toString('binary');
|
|
@@ -1726,7 +1776,7 @@ const RxFrameNtf = UnetMessages.RxFrameNtf;
|
|
|
1726
1776
|
*
|
|
1727
1777
|
* @class UnetSocket
|
|
1728
1778
|
* @param {string} [hostname] - hostname/ip address of the master container to connect to
|
|
1729
|
-
* @param {
|
|
1779
|
+
* @param {string} [port] - port number of the master container to connect to
|
|
1730
1780
|
* @param {string} [path=''] - path of the master container to connect to (for WebSockets)
|
|
1731
1781
|
* @returns {Promise<UnetSocket>} - Promise which resolves to the UnetSocket object being constructed
|
|
1732
1782
|
*
|