vrpc 2.5.0 → 3.0.0-alpha.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/CHANGELOG.md +66 -0
- package/README.md +33 -56
- package/binding.gyp.no-auto +4 -26
- package/browser/vrpc.js +1 -1
- package/index.js +2 -2
- package/package.json +13 -17
- package/vrpc/VrpcAdapter.js +275 -233
- package/vrpc/VrpcAgent.js +204 -185
- package/vrpc/{VrpcRemote.js → VrpcClient.js} +295 -288
- package/vrpc/VrpcNative.js +307 -0
- package/vrpc/{vrpc.hpp → adapter.hpp} +1001 -1115
- package/vrpc/addon.cpp +5 -5
- package/vrpc/json.hpp +1769 -870
- package/vrpc/vrpc-agent-js +4 -4
- package/README.rst +0 -18
- package/third_party/include/catch.hpp +0 -12749
- package/third_party/install.sh +0 -22
- package/vrpc/VrpcLocal.js +0 -264
- package/vrpc/VrpcLocal.py +0 -171
- package/vrpc/__init__.py +0 -1
- package/vrpc/module.cpp +0 -183
|
@@ -10,9 +10,9 @@ __\/\\\_______\/\\\__/\\\///////\\\___\/\\\/////////\\\____/\\\////////__
|
|
|
10
10
|
________\///________\///________\///__\///___________________\/////////__
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
Non-intrusively
|
|
13
|
+
Non-intrusively adapts code and provides access in form of asynchronous remote
|
|
14
14
|
procedure calls (RPC).
|
|
15
|
-
Author: Dr. Burkhard C. Heisen (https://github.com/
|
|
15
|
+
Author: Dr. Burkhard C. Heisen (https://github.com/heisenware/vrpc)
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
|
@@ -39,16 +39,19 @@ SOFTWARE.
|
|
|
39
39
|
|
|
40
40
|
const os = require('os')
|
|
41
41
|
const crypto = require('crypto')
|
|
42
|
+
const { nanoid } = require('nanoid')
|
|
42
43
|
const mqtt = require('mqtt')
|
|
43
44
|
const EventEmitter = require('events')
|
|
44
45
|
|
|
46
|
+
const VRPC_PROTOCOL_VERSION = 3
|
|
47
|
+
|
|
45
48
|
/**
|
|
46
49
|
* Client capable of creating proxy objects and remotely calling
|
|
47
50
|
* functions as provided through one or more (distributed) agents.
|
|
48
51
|
*
|
|
49
52
|
* @extends EventEmitter
|
|
50
53
|
*/
|
|
51
|
-
class
|
|
54
|
+
class VrpcClient extends EventEmitter {
|
|
52
55
|
/**
|
|
53
56
|
* Constructs a remote client, able to communicate with any distributed agents
|
|
54
57
|
*
|
|
@@ -66,7 +69,7 @@ class VrpcRemote extends EventEmitter {
|
|
|
66
69
|
* @param {Object} [options.log=console] Log object (must support debug, info, warn, and error level)
|
|
67
70
|
* @param {Boolean} [options.bestEffort=false] If true, message will be sent with best effort, i.e. no caching if offline
|
|
68
71
|
* @example
|
|
69
|
-
* const client = new
|
|
72
|
+
* const client = new VrpcClient({
|
|
70
73
|
* domain: 'public.vrpc',
|
|
71
74
|
* broker: 'mqtt://vrpc.io'
|
|
72
75
|
* })
|
|
@@ -86,11 +89,15 @@ class VrpcRemote extends EventEmitter {
|
|
|
86
89
|
// domain sanity check
|
|
87
90
|
if (!domain) throw new Error('The domain must be specified')
|
|
88
91
|
if (domain.match(/[+/#*]/)) {
|
|
89
|
-
throw new Error(
|
|
92
|
+
throw new Error(
|
|
93
|
+
'The domain must NOT contain any of those characters: "+", "/", "#", "*"'
|
|
94
|
+
)
|
|
90
95
|
}
|
|
91
96
|
// agent sanity check
|
|
92
97
|
if (agent.match(/[+/#]/)) {
|
|
93
|
-
throw new Error(
|
|
98
|
+
throw new Error(
|
|
99
|
+
'The agent must NOT contain any of those characters: "+", "/", "#"'
|
|
100
|
+
)
|
|
94
101
|
}
|
|
95
102
|
this._token = token
|
|
96
103
|
this._username = username
|
|
@@ -101,12 +108,13 @@ class VrpcRemote extends EventEmitter {
|
|
|
101
108
|
this._timeout = timeout
|
|
102
109
|
this._qos = this._qos = bestEffort ? 0 : 1
|
|
103
110
|
|
|
104
|
-
this._instance =
|
|
111
|
+
this._instance = nanoid(8)
|
|
105
112
|
this._mqttClientId = this._createMqttClientId()
|
|
106
113
|
this._vrpcClientId = this._createVrpcClientId()
|
|
107
114
|
this._agents = {}
|
|
108
115
|
this._eventEmitter = new EventEmitter()
|
|
109
116
|
this._invokeId = 0
|
|
117
|
+
this._proxyId = 0
|
|
110
118
|
this._client = null
|
|
111
119
|
this._cachedSubscriptions = new Map()
|
|
112
120
|
this._proxies = {}
|
|
@@ -118,6 +126,15 @@ class VrpcRemote extends EventEmitter {
|
|
|
118
126
|
}
|
|
119
127
|
}
|
|
120
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Provides a unique id for this client instance
|
|
131
|
+
*
|
|
132
|
+
* @returns {String} clientId
|
|
133
|
+
*/
|
|
134
|
+
getClientId () {
|
|
135
|
+
return this._vrpcClientId
|
|
136
|
+
}
|
|
137
|
+
|
|
121
138
|
/**
|
|
122
139
|
* Actually connects to the MQTT broker.
|
|
123
140
|
*
|
|
@@ -154,15 +171,15 @@ class VrpcRemote extends EventEmitter {
|
|
|
154
171
|
if (password === undefined) delete options.password
|
|
155
172
|
this._client = mqtt.connect(this._broker, options)
|
|
156
173
|
|
|
157
|
-
this._client.on('error',
|
|
174
|
+
this._client.on('error', err => {
|
|
158
175
|
this.emit('error', err)
|
|
159
176
|
})
|
|
160
177
|
|
|
161
|
-
this._client.stream.on('error',
|
|
178
|
+
this._client.stream.on('error', err => {
|
|
162
179
|
this.emit('error', err)
|
|
163
180
|
})
|
|
164
181
|
|
|
165
|
-
this.on('error',
|
|
182
|
+
this.on('error', err => {
|
|
166
183
|
this._log.debug(`Encountered MQTT error: ${err.message}`)
|
|
167
184
|
})
|
|
168
185
|
|
|
@@ -194,7 +211,7 @@ class VrpcRemote extends EventEmitter {
|
|
|
194
211
|
this._agents[agent].hostname = hostname
|
|
195
212
|
this._agents[agent].version = version
|
|
196
213
|
this.emit('agent', { domain, agent, status, hostname, version })
|
|
197
|
-
|
|
214
|
+
// ClassInfo message
|
|
198
215
|
} else if (instance === '__classInfo__') {
|
|
199
216
|
// Json properties: { klass, instances, memberFunctions, staticFunctions }
|
|
200
217
|
const json = JSON.parse(message.toString())
|
|
@@ -212,24 +229,23 @@ class VrpcRemote extends EventEmitter {
|
|
|
212
229
|
staticFunctions,
|
|
213
230
|
meta
|
|
214
231
|
} = json
|
|
215
|
-
if (removed.length !== 0)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
'
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
// RPC message
|
|
232
|
+
if (removed.length !== 0)
|
|
233
|
+
this.emit('instanceGone', removed, { domain, agent, className })
|
|
234
|
+
if (added.length !== 0)
|
|
235
|
+
this.emit('instanceNew', added, { domain, agent, className })
|
|
236
|
+
this.emit('class', {
|
|
237
|
+
domain,
|
|
238
|
+
agent,
|
|
239
|
+
className,
|
|
240
|
+
instances,
|
|
241
|
+
memberFunctions,
|
|
242
|
+
staticFunctions,
|
|
243
|
+
meta
|
|
244
|
+
})
|
|
245
|
+
// RPC message
|
|
230
246
|
} else {
|
|
231
|
-
const {
|
|
232
|
-
this._eventEmitter.emit(
|
|
247
|
+
const { i, a, e, r } = JSON.parse(message.toString())
|
|
248
|
+
this._eventEmitter.emit(i, { a, e, r })
|
|
233
249
|
}
|
|
234
250
|
})
|
|
235
251
|
await new Promise((resolve, reject) => {
|
|
@@ -243,11 +259,6 @@ class VrpcRemote extends EventEmitter {
|
|
|
243
259
|
})
|
|
244
260
|
}
|
|
245
261
|
|
|
246
|
-
async connected () {
|
|
247
|
-
this._indicateDeprecation('VrpcRemote.connected(): This API usage is deprecated, use `connect()` instead.')
|
|
248
|
-
return this.connect()
|
|
249
|
-
}
|
|
250
|
-
|
|
251
262
|
/**
|
|
252
263
|
* Creates a new remote instance and provides a proxy to it.
|
|
253
264
|
*
|
|
@@ -296,23 +307,20 @@ class VrpcRemote extends EventEmitter {
|
|
|
296
307
|
*/
|
|
297
308
|
async create ({
|
|
298
309
|
className,
|
|
299
|
-
instance,
|
|
310
|
+
instance = nanoid(8),
|
|
300
311
|
args = [],
|
|
301
312
|
agent = this._agent,
|
|
302
|
-
cacheProxy = false
|
|
313
|
+
cacheProxy = false,
|
|
314
|
+
isIsolated = false
|
|
303
315
|
} = {}) {
|
|
304
316
|
if (agent === '*') throw new Error('Agent must be specified')
|
|
305
|
-
const data = instance ? { _1: instance } : {}
|
|
306
|
-
const offset = instance ? 2 : 1
|
|
307
|
-
args.forEach((value, index) => {
|
|
308
|
-
data[`_${index + offset}`] = value
|
|
309
|
-
})
|
|
310
317
|
const json = {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
318
|
+
c: className,
|
|
319
|
+
f: isIsolated ? '__createIsolated__' : '__createShared__',
|
|
320
|
+
i: `${this._instance}-${this._invokeId++ % Number.MAX_SAFE_INTEGER}`,
|
|
321
|
+
s: `${this._domain}/${os.hostname()}/${this._instance}`,
|
|
322
|
+
a: [instance, ...args],
|
|
323
|
+
v: VRPC_PROTOCOL_VERSION
|
|
316
324
|
}
|
|
317
325
|
const proxy = await this._getProxy(agent, className, json)
|
|
318
326
|
if (instance && cacheProxy) this._proxies[instance] = proxy
|
|
@@ -342,11 +350,12 @@ class VrpcRemote extends EventEmitter {
|
|
|
342
350
|
instance: instanceString
|
|
343
351
|
} = await this._getInstanceData(instance, options)
|
|
344
352
|
return this._createProxy(agent, className, instanceString)
|
|
345
|
-
} else {
|
|
353
|
+
} else {
|
|
354
|
+
// deprecate this
|
|
346
355
|
this._indicateDeprecation(
|
|
347
|
-
'
|
|
348
|
-
|
|
349
|
-
|
|
356
|
+
'VrpcClient.getInstance(): ' +
|
|
357
|
+
'Using an object as single argument is deprecated, ' +
|
|
358
|
+
'use "getInstance(instance, options)" instead.'
|
|
350
359
|
)
|
|
351
360
|
const fakedOptions = { ...instance }
|
|
352
361
|
const fakedInstance = fakedOptions.instance
|
|
@@ -377,21 +386,23 @@ class VrpcRemote extends EventEmitter {
|
|
|
377
386
|
if (typeof instance === 'string') {
|
|
378
387
|
instanceData = await this._getInstanceData(instance)
|
|
379
388
|
if (options) instanceData = { ...options, ...instanceData }
|
|
380
|
-
} else {
|
|
389
|
+
} else {
|
|
390
|
+
// deprecate this
|
|
381
391
|
this._indicateDeprecation(
|
|
382
|
-
'
|
|
383
|
-
|
|
384
|
-
|
|
392
|
+
'VrpcClient.delete(): ' +
|
|
393
|
+
'Using an object as single argument is deprecated, ' +
|
|
394
|
+
'use "delete(instance, options)" instead.'
|
|
385
395
|
)
|
|
386
396
|
instanceData = { ...instanceData, ...instance }
|
|
387
397
|
}
|
|
388
398
|
const { agent, className, instance: instanceString } = instanceData
|
|
389
399
|
const json = {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
400
|
+
c: className,
|
|
401
|
+
f: '__delete__',
|
|
402
|
+
i: `${this._instance}-${this._invokeId++ % Number.MAX_SAFE_INTEGER}`,
|
|
403
|
+
s: `${this._domain}/${os.hostname()}/${this._instance}`,
|
|
404
|
+
a: [instanceString],
|
|
405
|
+
v: VRPC_PROTOCOL_VERSION
|
|
395
406
|
}
|
|
396
407
|
const topic = `${this._domain}/${agent}/${className}/__static__/__delete__`
|
|
397
408
|
this._mqttPublish(topic, JSON.stringify(json))
|
|
@@ -415,12 +426,15 @@ class VrpcRemote extends EventEmitter {
|
|
|
415
426
|
args = [],
|
|
416
427
|
agent = this._agent
|
|
417
428
|
} = {}) {
|
|
429
|
+
const wrapped = this._wrapArguments(className, functionName, ...args)
|
|
430
|
+
if (!wrapped) return // Skipping remote call -> handled locally
|
|
418
431
|
const json = {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
432
|
+
c: className,
|
|
433
|
+
f: functionName,
|
|
434
|
+
i: `${this._instance}-${this._invokeId++ % Number.MAX_SAFE_INTEGER}`,
|
|
435
|
+
s: this._vrpcClientId,
|
|
436
|
+
a: wrapped,
|
|
437
|
+
v: VRPC_PROTOCOL_VERSION
|
|
424
438
|
}
|
|
425
439
|
const topic = `${this._domain}/${agent}/${className}/__static__/${functionName}`
|
|
426
440
|
await this._waitUntilClassIsOnline(agent, className)
|
|
@@ -430,19 +444,23 @@ class VrpcRemote extends EventEmitter {
|
|
|
430
444
|
|
|
431
445
|
/**
|
|
432
446
|
* Calls the same function on all instances of a given class and returns an
|
|
433
|
-
* aggregated result.
|
|
447
|
+
* aggregated result. It as well allows for batch event and callback
|
|
448
|
+
* registrations. In this case the instanceId of the emitter is injected as
|
|
449
|
+
* first argument of any event callback.
|
|
434
450
|
*
|
|
435
451
|
* NOTE: When no agent was specified as class default and no agent is
|
|
436
452
|
* specified when calling this function, callAll will act on the requested
|
|
437
|
-
* class across all available agents. The same is true when explicitly using
|
|
438
|
-
*
|
|
453
|
+
* class across all available agents. The same is true when explicitly using a
|
|
454
|
+
* wildcard (*) as agent value.
|
|
439
455
|
*
|
|
440
456
|
* @param {Object} options
|
|
441
457
|
* @param {String} options.className Name of the static function's class
|
|
442
|
-
* @param {Array} [options.args] Positional arguments of the static function
|
|
443
|
-
*
|
|
444
|
-
* @
|
|
445
|
-
*
|
|
458
|
+
* @param {Array} [options.args] Positional arguments of the static function
|
|
459
|
+
* call
|
|
460
|
+
* @param {String} [options.agent] Agent name. If not provided class default
|
|
461
|
+
* is used
|
|
462
|
+
* @returns {Promise<Object[]>} An array of objects `{ id, val, err }`
|
|
463
|
+
* carrying the instance id, the return value and potential errors
|
|
446
464
|
*/
|
|
447
465
|
async callAll ({
|
|
448
466
|
className,
|
|
@@ -450,20 +468,26 @@ class VrpcRemote extends EventEmitter {
|
|
|
450
468
|
args = [],
|
|
451
469
|
agent = this._agent
|
|
452
470
|
} = {}) {
|
|
453
|
-
const data = { _1: functionName }
|
|
454
|
-
args.forEach((value, index) => (data[`_${index + 2}`] = value))
|
|
455
471
|
const json = {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
472
|
+
c: className,
|
|
473
|
+
f: functionName,
|
|
474
|
+
i: `${this._instance}-${this._invokeId++ % Number.MAX_SAFE_INTEGER}`,
|
|
475
|
+
s: this._vrpcClientId,
|
|
476
|
+
a: [],
|
|
477
|
+
v: VRPC_PROTOCOL_VERSION
|
|
461
478
|
}
|
|
462
479
|
if (agent === '*') {
|
|
463
480
|
const result = []
|
|
464
481
|
const agents = this.getAvailableAgents()
|
|
465
482
|
for (const x of agents) {
|
|
466
483
|
const topic = `${this._domain}/${x}/${className}/__static__/__callAll__`
|
|
484
|
+
const wrapped = this._wrapArguments(
|
|
485
|
+
`${x}-${className}`,
|
|
486
|
+
functionName,
|
|
487
|
+
...args
|
|
488
|
+
)
|
|
489
|
+
if (!wrapped) continue // using cache
|
|
490
|
+
json.a = [functionName, ...wrapped]
|
|
467
491
|
await this._waitUntilClassIsOnline(x, className)
|
|
468
492
|
this._mqttPublish(topic, JSON.stringify(json))
|
|
469
493
|
const tmp = await this._handleAgentAnswer(json)
|
|
@@ -472,41 +496,22 @@ class VrpcRemote extends EventEmitter {
|
|
|
472
496
|
return result
|
|
473
497
|
}
|
|
474
498
|
const topic = `${this._domain}/${agent}/${className}/__static__/__callAll__`
|
|
499
|
+
const wrapped = this._wrapArguments(
|
|
500
|
+
`${agent}-${className}`,
|
|
501
|
+
functionName,
|
|
502
|
+
...args
|
|
503
|
+
)
|
|
504
|
+
if (!wrapped) return // using cache
|
|
505
|
+
json.a = [functionName, ...wrapped]
|
|
475
506
|
await this._waitUntilClassIsOnline(agent, className)
|
|
476
507
|
this._mqttPublish(topic, JSON.stringify(json))
|
|
477
508
|
return this._handleAgentAnswer(json)
|
|
478
509
|
}
|
|
479
510
|
|
|
480
|
-
/**
|
|
481
|
-
* Retrieves all agents, instances, classes, member and static
|
|
482
|
-
* functions potentially available for remote control.
|
|
483
|
-
* @deprecated
|
|
484
|
-
* @returns {Object} SystemInformation
|
|
485
|
-
* ```ts
|
|
486
|
-
* type SystemInformation = {
|
|
487
|
-
* [domain].agents[agent].status: string, // 'offline' or 'online'
|
|
488
|
-
* [domain].agents[agent].hostname: string,
|
|
489
|
-
* [domain].agents[agent].version: string,
|
|
490
|
-
* [domain].agents[agent].classes[className].instances: string[],
|
|
491
|
-
* [domain].agents[agent].classes[className].memberFunctions: string[],
|
|
492
|
-
* [domain].agents[agent].classes[className].staticFunctions: string[],
|
|
493
|
-
* [domain].agents[agent].classes[className].meta?: MetaData
|
|
494
|
-
* }
|
|
495
|
-
* ```
|
|
496
|
-
*/
|
|
497
|
-
getAvailabilities () {
|
|
498
|
-
this._indicateDeprecation(
|
|
499
|
-
'VrpcRemote.getAvailabilities(): ' +
|
|
500
|
-
'This function is deprecated and will be removed soon, ' +
|
|
501
|
-
'use `getSystemInformation()` instead.'
|
|
502
|
-
)
|
|
503
|
-
return { [this._domain]: { agents: this._agents } }
|
|
504
|
-
}
|
|
505
|
-
|
|
506
511
|
/**
|
|
507
512
|
* Retrieves all information about the currently available components.
|
|
508
513
|
*
|
|
509
|
-
|
|
514
|
+
* @returns {Object} SystemInformation
|
|
510
515
|
* ```ts
|
|
511
516
|
* type SystemInformation = {
|
|
512
517
|
* [agent].status: string, // 'offline' or 'online'
|
|
@@ -523,21 +528,6 @@ class VrpcRemote extends EventEmitter {
|
|
|
523
528
|
return this._agents
|
|
524
529
|
}
|
|
525
530
|
|
|
526
|
-
/**
|
|
527
|
-
* Retrieves all domains on which agents can be remote controlled
|
|
528
|
-
*
|
|
529
|
-
* @deprecated
|
|
530
|
-
* @returns {Array} Array of domain names
|
|
531
|
-
*/
|
|
532
|
-
getAvailableDomains () {
|
|
533
|
-
this._indicateDeprecation(
|
|
534
|
-
'VrpcRemote.getAvailableDomains(): ' +
|
|
535
|
-
'this function will be removed in the next major release, as the client' +
|
|
536
|
-
'works with a single domain anyways'
|
|
537
|
-
)
|
|
538
|
-
return [this._domain]
|
|
539
|
-
}
|
|
540
|
-
|
|
541
531
|
/**
|
|
542
532
|
* Retrieves all available agents.
|
|
543
533
|
*
|
|
@@ -550,8 +540,8 @@ class VrpcRemote extends EventEmitter {
|
|
|
550
540
|
// `options = {}` was `domain = this._domain` before
|
|
551
541
|
if (typeof options === 'string') {
|
|
552
542
|
this._indicateDeprecation(
|
|
553
|
-
'
|
|
554
|
-
|
|
543
|
+
'VrpcClient.getAvailableAgents(): ' +
|
|
544
|
+
'Providing a domain here has no effect and will be an error in future.'
|
|
555
545
|
)
|
|
556
546
|
options = { mustBeOnline: true }
|
|
557
547
|
}
|
|
@@ -578,16 +568,19 @@ class VrpcRemote extends EventEmitter {
|
|
|
578
568
|
* @param {Boolean} [options.mustBeOnline=true] Only retrieve currently online classes
|
|
579
569
|
* @returns {Array} Array of class names.
|
|
580
570
|
*/
|
|
581
|
-
getAvailableClasses (
|
|
571
|
+
getAvailableClasses (
|
|
572
|
+
options = { agent: this._agent, mustBeOnline: true },
|
|
573
|
+
domain
|
|
574
|
+
) {
|
|
582
575
|
/// DEPRECATION INFORMATION AND WORKAROUND - TO BE REMOVED IN 3.x
|
|
583
576
|
let agent = this._agent
|
|
584
577
|
let mustBeOnline = true
|
|
585
578
|
// `options = {}` was `agent = this._agent` before
|
|
586
579
|
if (typeof options === 'string') {
|
|
587
580
|
this._indicateDeprecation(
|
|
588
|
-
'
|
|
589
|
-
|
|
590
|
-
|
|
581
|
+
'VrpcClient.getAvailableClasses(): ' +
|
|
582
|
+
'setting the agent as string argument is deprecated.`' +
|
|
583
|
+
'Use `{ agent: <myAgent> }` instead.'
|
|
591
584
|
)
|
|
592
585
|
agent = options
|
|
593
586
|
} else {
|
|
@@ -597,8 +590,8 @@ class VrpcRemote extends EventEmitter {
|
|
|
597
590
|
// was `domain = this._domain` before
|
|
598
591
|
if (domain) {
|
|
599
592
|
this._indicateDeprecation(
|
|
600
|
-
'
|
|
601
|
-
|
|
593
|
+
'VrpcClient.getAvailableClasses(): ' +
|
|
594
|
+
'Providing a domain here has no effect and will be an error in future.'
|
|
602
595
|
)
|
|
603
596
|
}
|
|
604
597
|
///
|
|
@@ -630,9 +623,9 @@ class VrpcRemote extends EventEmitter {
|
|
|
630
623
|
// `options = {}` was `agent = this._agent` before
|
|
631
624
|
if (typeof options === 'string') {
|
|
632
625
|
this._indicateDeprecation(
|
|
633
|
-
'
|
|
634
|
-
|
|
635
|
-
|
|
626
|
+
'VrpcClient.getAvailableInstances(): ' +
|
|
627
|
+
'Setting the agent as string argument is deprecated.`' +
|
|
628
|
+
'Use `{ agent: <myAgent> }` instead.'
|
|
636
629
|
)
|
|
637
630
|
agent = options
|
|
638
631
|
} else {
|
|
@@ -642,8 +635,8 @@ class VrpcRemote extends EventEmitter {
|
|
|
642
635
|
// was `domain = this._domain` before
|
|
643
636
|
if (domain) {
|
|
644
637
|
this._indicateDeprecation(
|
|
645
|
-
'
|
|
646
|
-
|
|
638
|
+
'VrpcClient.getAvailableInstances(): ' +
|
|
639
|
+
'Providing a domain here has no effect and will be an error in future.'
|
|
647
640
|
)
|
|
648
641
|
}
|
|
649
642
|
///
|
|
@@ -675,9 +668,9 @@ class VrpcRemote extends EventEmitter {
|
|
|
675
668
|
// `options = {}` was `agent = this._agent` before
|
|
676
669
|
if (typeof options === 'string') {
|
|
677
670
|
this._indicateDeprecation(
|
|
678
|
-
'
|
|
679
|
-
|
|
680
|
-
|
|
671
|
+
'VrpcClient.getAvailableMemberFunctions(): ' +
|
|
672
|
+
'Setting the agent as string argument is deprecated.`' +
|
|
673
|
+
'Use `{ agent: <myAgent> }` instead.'
|
|
681
674
|
)
|
|
682
675
|
agent = options
|
|
683
676
|
} else {
|
|
@@ -687,8 +680,8 @@ class VrpcRemote extends EventEmitter {
|
|
|
687
680
|
// was `domain = this._domain` before
|
|
688
681
|
if (domain) {
|
|
689
682
|
this._indicateDeprecation(
|
|
690
|
-
'
|
|
691
|
-
|
|
683
|
+
'VrpcClient.getAvailableMemberFunctions(): ' +
|
|
684
|
+
'Providing a domain here has no effect and will be an error in future.'
|
|
692
685
|
)
|
|
693
686
|
}
|
|
694
687
|
///
|
|
@@ -722,9 +715,9 @@ class VrpcRemote extends EventEmitter {
|
|
|
722
715
|
// `options = {}` was `agent = this._agent` before
|
|
723
716
|
if (typeof options === 'string') {
|
|
724
717
|
this._indicateDeprecation(
|
|
725
|
-
'
|
|
726
|
-
|
|
727
|
-
|
|
718
|
+
'VrpcClient.getAvailableStaticFunctions(): ' +
|
|
719
|
+
'Setting the agent as string argument is deprecated.`' +
|
|
720
|
+
'Use `{ agent: <myAgent> }` instead.'
|
|
728
721
|
)
|
|
729
722
|
agent = options
|
|
730
723
|
} else {
|
|
@@ -734,8 +727,8 @@ class VrpcRemote extends EventEmitter {
|
|
|
734
727
|
// was `domain = this._domain` before
|
|
735
728
|
if (domain) {
|
|
736
729
|
this._indicateDeprecation(
|
|
737
|
-
'
|
|
738
|
-
|
|
730
|
+
'VrpcClient.getAvailableStaticFunctions(): ' +
|
|
731
|
+
'Providing a domain here has no effect and will be an error in future.'
|
|
739
732
|
)
|
|
740
733
|
}
|
|
741
734
|
///
|
|
@@ -757,10 +750,7 @@ class VrpcRemote extends EventEmitter {
|
|
|
757
750
|
* @param {String} options.agent Agent name. If not provided class default is used
|
|
758
751
|
* @returns {Promise} Promise that resolves once re-connected
|
|
759
752
|
*/
|
|
760
|
-
async reconnectWithToken (
|
|
761
|
-
token,
|
|
762
|
-
{ agent = this._agent } = {}
|
|
763
|
-
) {
|
|
753
|
+
async reconnectWithToken (token, { agent = this._agent } = {}) {
|
|
764
754
|
this._token = token
|
|
765
755
|
this._agent = agent
|
|
766
756
|
this._client.end(() => this.connect())
|
|
@@ -799,19 +789,29 @@ class VrpcRemote extends EventEmitter {
|
|
|
799
789
|
async end () {
|
|
800
790
|
this._mqttPublish(
|
|
801
791
|
`${this._vrpcClientId}/__clientInfo__`,
|
|
802
|
-
JSON.stringify({ status: 'offline' })
|
|
792
|
+
JSON.stringify({ status: 'offline', v: VRPC_PROTOCOL_VERSION })
|
|
803
793
|
)
|
|
804
794
|
return new Promise(resolve => this._client.end(false, {}, resolve))
|
|
805
795
|
}
|
|
806
796
|
|
|
807
797
|
_createMqttClientId () {
|
|
808
|
-
const clientInfo =
|
|
809
|
-
|
|
810
|
-
|
|
798
|
+
const clientInfo =
|
|
799
|
+
os.arch() +
|
|
800
|
+
JSON.stringify(os.cpus()) +
|
|
801
|
+
os.homedir() +
|
|
802
|
+
os.hostname() +
|
|
803
|
+
JSON.stringify(os.networkInterfaces()) +
|
|
804
|
+
os.platform() +
|
|
805
|
+
os.release() +
|
|
806
|
+
os.totalmem() +
|
|
807
|
+
os.type()
|
|
811
808
|
// console.log('ClientInfo:', clientInfo)
|
|
812
|
-
const md5 = crypto
|
|
813
|
-
|
|
814
|
-
|
|
809
|
+
const md5 = crypto
|
|
810
|
+
.createHash('md5')
|
|
811
|
+
.update(clientInfo)
|
|
812
|
+
.digest('hex')
|
|
813
|
+
.substr(0, 12)
|
|
814
|
+
return `vc3${this._instance}${md5}` // 3 + 8 + 12 = 23 (max clientId)
|
|
815
815
|
}
|
|
816
816
|
|
|
817
817
|
_createVrpcClientId () {
|
|
@@ -819,29 +819,44 @@ class VrpcRemote extends EventEmitter {
|
|
|
819
819
|
}
|
|
820
820
|
|
|
821
821
|
_mqttPublish (topic, message, options) {
|
|
822
|
-
this._client.publish(
|
|
823
|
-
|
|
824
|
-
|
|
822
|
+
this._client.publish(
|
|
823
|
+
topic,
|
|
824
|
+
message,
|
|
825
|
+
{ qos: this._qos, ...options },
|
|
826
|
+
err => {
|
|
827
|
+
if (err) {
|
|
828
|
+
this._log.warn(
|
|
829
|
+
`Could not publish MQTT message because: ${err.message}`
|
|
830
|
+
)
|
|
831
|
+
}
|
|
825
832
|
}
|
|
826
|
-
|
|
833
|
+
)
|
|
827
834
|
}
|
|
828
835
|
|
|
829
836
|
_mqttSubscribe (topic, options) {
|
|
830
|
-
this._client.subscribe(
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
if (
|
|
835
|
-
this._log.
|
|
837
|
+
this._client.subscribe(
|
|
838
|
+
topic,
|
|
839
|
+
{ qos: this._qos, ...options },
|
|
840
|
+
(err, granted) => {
|
|
841
|
+
if (err) {
|
|
842
|
+
this._log.warn(
|
|
843
|
+
`Could not subscribe to topic: ${topic} because: ${err.message}`
|
|
844
|
+
)
|
|
845
|
+
} else {
|
|
846
|
+
if (granted.length === 0) {
|
|
847
|
+
this._log.debug(`Already subscribed to: ${topic}`)
|
|
848
|
+
}
|
|
836
849
|
}
|
|
837
850
|
}
|
|
838
|
-
|
|
851
|
+
)
|
|
839
852
|
}
|
|
840
853
|
|
|
841
854
|
_mqttUnsubscribe (topic, options) {
|
|
842
|
-
this._client.unsubscribe(topic, options,
|
|
855
|
+
this._client.unsubscribe(topic, options, err => {
|
|
843
856
|
if (err) {
|
|
844
|
-
this._log.warn(
|
|
857
|
+
this._log.warn(
|
|
858
|
+
`Could not unsubscribe from topic: ${topic} because: ${err.message}`
|
|
859
|
+
)
|
|
845
860
|
}
|
|
846
861
|
})
|
|
847
862
|
}
|
|
@@ -853,25 +868,22 @@ class VrpcRemote extends EventEmitter {
|
|
|
853
868
|
}
|
|
854
869
|
|
|
855
870
|
async _getProxy (agent, className, json) {
|
|
856
|
-
const {
|
|
857
|
-
const topic = `${this._domain}/${agent}/${className}/__static__/${
|
|
871
|
+
const { f, i } = json
|
|
872
|
+
const topic = `${this._domain}/${agent}/${className}/__static__/${f}`
|
|
858
873
|
await this._waitUntilClassIsOnline(agent, className)
|
|
859
874
|
this._mqttPublish(topic, JSON.stringify(json))
|
|
860
875
|
return new Promise((resolve, reject) => {
|
|
861
876
|
const msg = `Proxy creation for class "${className}" on agent "${agent}" and domain "${this._domain}" timed out (> ${this._timeout} ms)`
|
|
862
|
-
const timer = setTimeout(
|
|
863
|
-
()
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
this._timeout
|
|
868
|
-
)
|
|
869
|
-
this._eventEmitter.once(json.id, data => {
|
|
877
|
+
const timer = setTimeout(() => {
|
|
878
|
+
this._eventEmitter.removeAllListeners(i)
|
|
879
|
+
reject(new Error(msg))
|
|
880
|
+
}, this._timeout)
|
|
881
|
+
this._eventEmitter.once(i, ({ e, r }) => {
|
|
870
882
|
clearTimeout(timer)
|
|
871
|
-
if (
|
|
872
|
-
reject(new Error(
|
|
883
|
+
if (e) {
|
|
884
|
+
reject(new Error(e))
|
|
873
885
|
} else {
|
|
874
|
-
const proxy = this._createProxy(agent, className,
|
|
886
|
+
const proxy = this._createProxy(agent, className, r)
|
|
875
887
|
resolve(proxy)
|
|
876
888
|
}
|
|
877
889
|
})
|
|
@@ -891,7 +903,11 @@ class VrpcRemote extends EventEmitter {
|
|
|
891
903
|
}
|
|
892
904
|
timer = setTimeout(() => {
|
|
893
905
|
this.removeListener('class', checkClass)
|
|
894
|
-
reject(
|
|
906
|
+
reject(
|
|
907
|
+
new Error(
|
|
908
|
+
`Proxy creation for class "${className}" on agent "${agent}" and domain "${this._domain}" timed out (> ${this._timeout} ms)`
|
|
909
|
+
)
|
|
910
|
+
)
|
|
895
911
|
}, this._timeout)
|
|
896
912
|
this.on('class', checkClass)
|
|
897
913
|
})
|
|
@@ -907,10 +923,11 @@ class VrpcRemote extends EventEmitter {
|
|
|
907
923
|
|
|
908
924
|
_createProxy (agent, className, instance) {
|
|
909
925
|
const targetTopic = `${this._domain}/${agent}/${className}/${instance}`
|
|
910
|
-
const proxyId =
|
|
926
|
+
const proxyId = `${this._instance}-${this._proxyId++}`
|
|
911
927
|
const proxy = {
|
|
912
|
-
|
|
913
|
-
|
|
928
|
+
vrpcClientId: this._vrpcClientId,
|
|
929
|
+
vrpcInstanceId: instance,
|
|
930
|
+
vrpcProxyId: proxyId
|
|
914
931
|
}
|
|
915
932
|
let functions = this._agents[agent].classes[className].memberFunctions
|
|
916
933
|
// Strip off argument signature
|
|
@@ -924,37 +941,37 @@ class VrpcRemote extends EventEmitter {
|
|
|
924
941
|
// Build proxy
|
|
925
942
|
uniqueFuncs.forEach(name => {
|
|
926
943
|
proxy[name] = async (...args) => {
|
|
944
|
+
const wrapped = this._wrapArguments(proxyId, name, ...args)
|
|
945
|
+
if (!wrapped) return // Skipping remote call -> handled locally
|
|
927
946
|
try {
|
|
928
947
|
const json = {
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
948
|
+
c: instance,
|
|
949
|
+
f: name,
|
|
950
|
+
i: `${this._instance}-${this._invokeId++ % Number.MAX_SAFE_INTEGER}`,
|
|
951
|
+
s: this._vrpcClientId,
|
|
952
|
+
a: wrapped,
|
|
953
|
+
v: VRPC_PROTOCOL_VERSION
|
|
934
954
|
}
|
|
935
|
-
// Skipping remote call -> handled locally
|
|
936
|
-
if (json.data === null) return
|
|
937
955
|
this._mqttPublish(`${targetTopic}/${name}`, JSON.stringify(json))
|
|
938
956
|
return this._handleAgentAnswer(json)
|
|
939
957
|
} catch (err) {
|
|
940
|
-
throw new Error(
|
|
958
|
+
throw new Error(
|
|
959
|
+
`Could not remotely call "${name}" because: ${err.message}`
|
|
960
|
+
)
|
|
941
961
|
}
|
|
942
962
|
}
|
|
943
963
|
})
|
|
944
964
|
return proxy
|
|
945
965
|
}
|
|
946
966
|
|
|
947
|
-
async _handleAgentAnswer ({
|
|
967
|
+
async _handleAgentAnswer ({ i, c, f }) {
|
|
948
968
|
return new Promise((resolve, reject) => {
|
|
949
|
-
const msg = `Function call "${
|
|
950
|
-
const timer = setTimeout(
|
|
951
|
-
()
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
this._timeout
|
|
956
|
-
)
|
|
957
|
-
this._eventEmitter.once(id, data => {
|
|
969
|
+
const msg = `Function call "${c}::${f}()" timed out (> ${this._timeout} ms)`
|
|
970
|
+
const timer = setTimeout(() => {
|
|
971
|
+
this._eventEmitter.removeAllListeners(i)
|
|
972
|
+
reject(new Error(msg))
|
|
973
|
+
}, this._timeout)
|
|
974
|
+
this._eventEmitter.once(i, data => {
|
|
958
975
|
clearTimeout(timer)
|
|
959
976
|
if (data.e) {
|
|
960
977
|
reject(new Error(data.e))
|
|
@@ -976,7 +993,7 @@ class VrpcRemote extends EventEmitter {
|
|
|
976
993
|
|
|
977
994
|
async _waitForInstance (instance, options = {}) {
|
|
978
995
|
return new Promise((resolve, reject) => {
|
|
979
|
-
const handler =
|
|
996
|
+
const handler = timer => (instances, { agent, className }) => {
|
|
980
997
|
if (instances.includes(instance)) {
|
|
981
998
|
if (options.agent && agent !== options.agent) return
|
|
982
999
|
if (options.className && className !== options.className) return
|
|
@@ -985,75 +1002,64 @@ class VrpcRemote extends EventEmitter {
|
|
|
985
1002
|
resolve({ agent, className, instance })
|
|
986
1003
|
}
|
|
987
1004
|
}
|
|
988
|
-
const timer = setTimeout(
|
|
989
|
-
()
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
},
|
|
994
|
-
this._timeout
|
|
995
|
-
)
|
|
1005
|
+
const timer = setTimeout(() => {
|
|
1006
|
+
this.removeListener('instanceNew', handler(timer))
|
|
1007
|
+
const msg = `Could not find instance: ${instance} (> ${this._timeout} ms)`
|
|
1008
|
+
reject(new Error(msg))
|
|
1009
|
+
}, this._timeout)
|
|
996
1010
|
this.on('instanceNew', handler(timer))
|
|
997
1011
|
})
|
|
998
1012
|
}
|
|
999
1013
|
|
|
1000
|
-
|
|
1001
|
-
const
|
|
1014
|
+
_wrapArguments (remoteId, functionName, ...args) {
|
|
1015
|
+
const wrapped = []
|
|
1002
1016
|
let isHandledLocally = false
|
|
1003
|
-
args.forEach((
|
|
1017
|
+
args.forEach((x, i) => {
|
|
1004
1018
|
// Check whether provided argument is a function
|
|
1005
|
-
if (this._isFunction(
|
|
1019
|
+
if (this._isFunction(x)) {
|
|
1006
1020
|
// Check special case of an event emitter registration
|
|
1007
1021
|
// We test three conditions:
|
|
1008
1022
|
// 1) functionName must be "on"
|
|
1009
1023
|
// 2) callback is second argument
|
|
1010
1024
|
// 3) first argument was string
|
|
1011
|
-
if (functionName === 'on' &&
|
|
1012
|
-
|
|
1013
|
-
typeof args[0] === 'string'
|
|
1014
|
-
) {
|
|
1015
|
-
const id = this._addEventSubscription(proxyId, args[0], value)
|
|
1025
|
+
if (functionName === 'on' && i === 1 && typeof args[0] === 'string') {
|
|
1026
|
+
const id = this._addEventSubscription(remoteId, args[0], x)
|
|
1016
1027
|
if (!id) isHandledLocally = true
|
|
1017
|
-
|
|
1028
|
+
wrapped.push(id)
|
|
1018
1029
|
} else if (
|
|
1019
1030
|
(functionName === 'off' || functionName === 'removeListener') &&
|
|
1020
|
-
|
|
1031
|
+
i === 1 &&
|
|
1021
1032
|
typeof args[0] === 'string'
|
|
1022
1033
|
) {
|
|
1023
|
-
const id = this._removeEventSubscription(
|
|
1034
|
+
const id = this._removeEventSubscription(remoteId, args[0], x)
|
|
1024
1035
|
if (!id) isHandledLocally = true
|
|
1025
|
-
|
|
1026
|
-
|
|
1036
|
+
wrapped.push(id)
|
|
1037
|
+
// Regular function callback
|
|
1027
1038
|
} else {
|
|
1028
|
-
const id = `__f__${
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
.map(x => data[x])
|
|
1034
|
-
value.apply(null, args) // This is the actual function call
|
|
1039
|
+
const id = `__f__${remoteId}-${functionName}-${i}-${this._invokeId++ %
|
|
1040
|
+
Number.MAX_SAFE_INTEGER}`
|
|
1041
|
+
wrapped.push(id)
|
|
1042
|
+
this._eventEmitter.once(id, ({ a }) => {
|
|
1043
|
+
x.apply(null, a) // This is the actual function call
|
|
1035
1044
|
})
|
|
1036
1045
|
}
|
|
1037
|
-
} else if (this._isEmitter(
|
|
1038
|
-
const { emitter, event } =
|
|
1039
|
-
const id = `__f__${
|
|
1040
|
-
|
|
1041
|
-
this._eventEmitter.on(id,
|
|
1042
|
-
|
|
1043
|
-
.filter(x => x[0] === '_')
|
|
1044
|
-
.map(x => data[x])
|
|
1045
|
-
emitter.emit(event, ...args)
|
|
1046
|
+
} else if (this._isEmitter(x)) {
|
|
1047
|
+
const { emitter, event } = x
|
|
1048
|
+
const id = `__f__${remoteId}-${functionName}-${i}-${event}`
|
|
1049
|
+
wrapped.push(id)
|
|
1050
|
+
this._eventEmitter.on(id, ({ a }) => {
|
|
1051
|
+
emitter.emit(event, ...a)
|
|
1046
1052
|
})
|
|
1047
1053
|
} else {
|
|
1048
|
-
|
|
1054
|
+
wrapped.push(x)
|
|
1049
1055
|
}
|
|
1050
1056
|
})
|
|
1051
1057
|
if (isHandledLocally) return null
|
|
1052
|
-
return
|
|
1058
|
+
return wrapped
|
|
1053
1059
|
}
|
|
1054
1060
|
|
|
1055
|
-
_addEventSubscription (
|
|
1056
|
-
const id = `__f__${
|
|
1061
|
+
_addEventSubscription (remoteId, event, callback) {
|
|
1062
|
+
const id = `__f__${remoteId}-${event}`
|
|
1057
1063
|
if (this._cachedSubscriptions.has(id)) {
|
|
1058
1064
|
this._cachedSubscriptions.get(id).on(id, callback)
|
|
1059
1065
|
return
|
|
@@ -1061,17 +1067,14 @@ class VrpcRemote extends EventEmitter {
|
|
|
1061
1067
|
const emitter = new EventEmitter()
|
|
1062
1068
|
emitter.on(id, callback)
|
|
1063
1069
|
this._cachedSubscriptions.set(id, emitter)
|
|
1064
|
-
this._eventEmitter.on(id, (
|
|
1065
|
-
|
|
1066
|
-
.filter(x => x[0] === '_')
|
|
1067
|
-
.map(x => data[x])
|
|
1068
|
-
emitter.emit(id, ...args)
|
|
1070
|
+
this._eventEmitter.on(id, ({ a }) => {
|
|
1071
|
+
emitter.emit(id, ...a)
|
|
1069
1072
|
})
|
|
1070
1073
|
return id
|
|
1071
1074
|
}
|
|
1072
1075
|
|
|
1073
|
-
_removeEventSubscription (
|
|
1074
|
-
const id = `__f__${
|
|
1076
|
+
_removeEventSubscription (remoteId, event, callback) {
|
|
1077
|
+
const id = `__f__${remoteId}-${event}`
|
|
1075
1078
|
if (this._cachedSubscriptions.has(id)) {
|
|
1076
1079
|
const emitter = this._cachedSubscriptions.get(id)
|
|
1077
1080
|
emitter.removeListener(id, callback)
|
|
@@ -1092,8 +1095,10 @@ class VrpcRemote extends EventEmitter {
|
|
|
1092
1095
|
_isFunction (variable) {
|
|
1093
1096
|
const getType = {}
|
|
1094
1097
|
const type = getType.toString.call(variable)
|
|
1095
|
-
return
|
|
1098
|
+
return (
|
|
1099
|
+
variable &&
|
|
1096
1100
|
(type === '[object Function]' || type === '[object AsyncFunction]')
|
|
1101
|
+
)
|
|
1097
1102
|
}
|
|
1098
1103
|
|
|
1099
1104
|
_isEmitter (variable) {
|
|
@@ -1109,7 +1114,9 @@ class VrpcRemote extends EventEmitter {
|
|
|
1109
1114
|
async _getInstanceData (instance, options = {}) {
|
|
1110
1115
|
const instanceData = this._getInstanceFromCache(instance, options)
|
|
1111
1116
|
if (!instanceData) {
|
|
1112
|
-
if (options.noWait)
|
|
1117
|
+
if (options.noWait) {
|
|
1118
|
+
throw new Error(`Could not find instance: ${instance}`)
|
|
1119
|
+
}
|
|
1113
1120
|
return this._waitForInstance(instance, options)
|
|
1114
1121
|
}
|
|
1115
1122
|
return instanceData
|
|
@@ -1148,7 +1155,7 @@ class VrpcRemote extends EventEmitter {
|
|
|
1148
1155
|
* This event is fired whenever an agent is added or removed, or whenever
|
|
1149
1156
|
* an agent changes its status (switches between online or offline).
|
|
1150
1157
|
*
|
|
1151
|
-
* @event
|
|
1158
|
+
* @event VrpcClient#agent
|
|
1152
1159
|
* @param {Object} info
|
|
1153
1160
|
* @param {String} info.domain - Domain name
|
|
1154
1161
|
* @param {String} info.agent - Agent name
|
|
@@ -1163,7 +1170,7 @@ class VrpcRemote extends EventEmitter {
|
|
|
1163
1170
|
* Emitted whenever a class is added or removed, or when instances
|
|
1164
1171
|
* or functions of this class have changed.
|
|
1165
1172
|
*
|
|
1166
|
-
* @event
|
|
1173
|
+
* @event VrpcClient#class
|
|
1167
1174
|
* @param {Object} info
|
|
1168
1175
|
* @param {String} info.domain - Domain name
|
|
1169
1176
|
* @param {String} info.agent - Agent name
|
|
@@ -1175,57 +1182,57 @@ class VrpcRemote extends EventEmitter {
|
|
|
1175
1182
|
*/
|
|
1176
1183
|
|
|
1177
1184
|
/**
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1185
|
+
* Event 'instanceNew'
|
|
1186
|
+
*
|
|
1187
|
+
* Emitted whenever a new instance was created.
|
|
1188
|
+
*
|
|
1189
|
+
* @event VrpcClient#instanceNew
|
|
1190
|
+
*
|
|
1191
|
+
* @param {Array.<String>} addedInstances - An array of newly added instances
|
|
1192
|
+
* @param {Object} info
|
|
1193
|
+
* @param {String} info.domain - Domain name
|
|
1194
|
+
* @param {String} info.agent - Agent name
|
|
1195
|
+
* @param {String} info.className - Class name
|
|
1196
|
+
*/
|
|
1190
1197
|
|
|
1191
1198
|
/**
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1199
|
+
* Event 'instanceGone'
|
|
1200
|
+
*
|
|
1201
|
+
* Emitted whenever a new instance was removed.
|
|
1202
|
+
*
|
|
1203
|
+
* @event VrpcClient#instanceGone
|
|
1204
|
+
*
|
|
1205
|
+
* @param {Array.<String>} removedInstances - An array of removed instances
|
|
1206
|
+
* @param {Object} info
|
|
1207
|
+
* @param {String} info.domain - Domain name
|
|
1208
|
+
* @param {String} info.agent - Agent name
|
|
1209
|
+
* @param {String} info.className - Class name
|
|
1210
|
+
*/
|
|
1204
1211
|
|
|
1205
1212
|
/**
|
|
1206
1213
|
* Event 'connect'
|
|
1207
1214
|
*
|
|
1208
1215
|
* Emitted on successful (re)connection (i.e. connack rc=0).
|
|
1209
1216
|
*
|
|
1210
|
-
* @event
|
|
1217
|
+
* @event VrpcClient#connect
|
|
1211
1218
|
* @type {Object}
|
|
1212
1219
|
* @property {Boolean} sessionPresent - A session from a previous connection is already present
|
|
1213
|
-
*/
|
|
1220
|
+
*/
|
|
1214
1221
|
|
|
1215
1222
|
/**
|
|
1216
1223
|
* Event 'reconnect'
|
|
1217
1224
|
*
|
|
1218
1225
|
* Emitted when a reconnect starts.
|
|
1219
1226
|
*
|
|
1220
|
-
* @event
|
|
1221
|
-
*/
|
|
1227
|
+
* @event VrpcClient#reconnect
|
|
1228
|
+
*/
|
|
1222
1229
|
|
|
1223
1230
|
/**
|
|
1224
1231
|
* Event 'close'
|
|
1225
1232
|
*
|
|
1226
1233
|
* Emitted after a disconnection.
|
|
1227
1234
|
*
|
|
1228
|
-
* @event
|
|
1235
|
+
* @event VrpcClient#close
|
|
1229
1236
|
*/
|
|
1230
1237
|
|
|
1231
1238
|
/**
|
|
@@ -1233,7 +1240,7 @@ class VrpcRemote extends EventEmitter {
|
|
|
1233
1240
|
*
|
|
1234
1241
|
* Emitted when the client goes offline.
|
|
1235
1242
|
*
|
|
1236
|
-
* @event
|
|
1243
|
+
* @event VrpcClient#offline
|
|
1237
1244
|
*/
|
|
1238
1245
|
|
|
1239
1246
|
/**
|
|
@@ -1248,7 +1255,7 @@ class VrpcRemote extends EventEmitter {
|
|
|
1248
1255
|
* - EADDRINUSE
|
|
1249
1256
|
* - ENOTFOUND
|
|
1250
1257
|
*
|
|
1251
|
-
* @event
|
|
1258
|
+
* @event VrpcClient#error
|
|
1252
1259
|
* @type {Object} Error
|
|
1253
1260
|
*/
|
|
1254
1261
|
|
|
@@ -1258,7 +1265,7 @@ class VrpcRemote extends EventEmitter {
|
|
|
1258
1265
|
* Emitted when mqtt.Client#end() is called. If a callback was passed to
|
|
1259
1266
|
* mqtt.Client#end(), this event is emitted once the callback returns.
|
|
1260
1267
|
*
|
|
1261
|
-
* @event
|
|
1268
|
+
* @event VrpcClient#end
|
|
1262
1269
|
*/
|
|
1263
1270
|
|
|
1264
|
-
module.exports =
|
|
1271
|
+
module.exports = VrpcClient
|