mqtt-plus 0.9.3 → 0.9.5
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 +126 -75
- package/doc/mqtt-plus-1-event-emission.d2 +18 -0
- package/doc/mqtt-plus-1-event-emission.svg +104 -0
- package/doc/mqtt-plus-2-stream-transfer.d2 +22 -0
- package/doc/mqtt-plus-2-stream-transfer.svg +108 -0
- package/doc/mqtt-plus-3-service-call.d2 +21 -0
- package/doc/mqtt-plus-3-service-call.svg +107 -0
- package/doc/mqtt-plus-4-resource-transfer.d2 +25 -0
- package/doc/mqtt-plus-4-resource-transfer.svg +111 -0
- package/doc/theme.d2 +40 -0
- package/dst-stage1/mqtt-plus-api.d.ts +26 -0
- package/dst-stage1/mqtt-plus-api.js +24 -0
- package/dst-stage1/mqtt-plus-base.d.ts +19 -0
- package/dst-stage1/mqtt-plus-base.js +114 -0
- package/dst-stage1/mqtt-plus-codec.d.ts +6 -0
- package/dst-stage1/mqtt-plus-codec.js +11 -0
- package/dst-stage1/mqtt-plus-event.d.ts +18 -0
- package/dst-stage1/mqtt-plus-event.js +103 -0
- package/dst-stage1/mqtt-plus-info.d.ts +16 -0
- package/dst-stage1/mqtt-plus-info.js +24 -0
- package/dst-stage1/mqtt-plus-msg.d.ts +28 -14
- package/dst-stage1/mqtt-plus-msg.js +84 -46
- package/dst-stage1/mqtt-plus-options.d.ts +20 -0
- package/dst-stage1/mqtt-plus-options.js +46 -0
- package/dst-stage1/mqtt-plus-receiver.d.ts +12 -0
- package/dst-stage1/mqtt-plus-receiver.js +42 -0
- package/dst-stage1/mqtt-plus-resource.d.ts +19 -0
- package/dst-stage1/mqtt-plus-resource.js +196 -0
- package/dst-stage1/mqtt-plus-service.d.ts +22 -0
- package/dst-stage1/mqtt-plus-service.js +220 -0
- package/dst-stage1/mqtt-plus-stream.d.ts +20 -0
- package/dst-stage1/mqtt-plus-stream.js +152 -0
- package/dst-stage1/mqtt-plus.d.ts +5 -104
- package/dst-stage1/mqtt-plus.js +4 -508
- package/dst-stage2/mqtt-plus.cjs.js +462 -263
- package/dst-stage2/mqtt-plus.esm.js +460 -262
- package/dst-stage2/mqtt-plus.umd.js +14 -14
- package/etc/d2.mts +21 -0
- package/etc/eslint.mts +1 -1
- package/etc/stx.conf +13 -1
- package/etc/tsc.tsbuildinfo +1 -1
- package/package.json +19 -5
- package/src/mqtt-plus-api.ts +66 -0
- package/src/mqtt-plus-base.ts +156 -0
- package/src/mqtt-plus-codec.ts +20 -0
- package/src/mqtt-plus-event.ts +164 -0
- package/src/mqtt-plus-info.ts +43 -0
- package/src/mqtt-plus-msg.ts +116 -58
- package/src/mqtt-plus-options.ts +70 -0
- package/src/mqtt-plus-receiver.ts +52 -0
- package/src/mqtt-plus-resource.ts +276 -0
- package/src/mqtt-plus-service.ts +292 -0
- package/src/mqtt-plus-stream.ts +222 -0
- package/src/mqtt-plus.ts +6 -765
- package/tst/mqtt-plus.spec.ts +271 -0
- package/tst/tsc.json +30 -0
package/README.md
CHANGED
|
@@ -22,10 +22,10 @@ $ npm install mqtt mqtt-plus
|
|
|
22
22
|
About
|
|
23
23
|
-----
|
|
24
24
|
|
|
25
|
-
This is **MQTT+**,
|
|
25
|
+
This is **MQTT+**, a companion addon API for the excellent
|
|
26
26
|
[MQTT](http://mqtt.org/) client TypeScript/JavaScript API
|
|
27
|
-
[MQTT.js](https://www.npmjs.com/package/mqtt),
|
|
28
|
-
communication patterns with
|
|
27
|
+
[MQTT.js](https://www.npmjs.com/package/mqtt), providing additional
|
|
28
|
+
communication patterns with type safety:
|
|
29
29
|
|
|
30
30
|
- **Event Emission**:
|
|
31
31
|
|
|
@@ -38,7 +38,9 @@ communication patterns with optional type safety:
|
|
|
38
38
|
|
|
39
39
|
In contrast to the regular MQTT message publish/subscribe, this
|
|
40
40
|
pattern allows to direct the event to particular subscribers and
|
|
41
|
-
provides optional information about the sender to subscribers.
|
|
41
|
+
provides optional information about the sender and receiver to subscribers.
|
|
42
|
+
|
|
43
|
+

|
|
42
44
|
|
|
43
45
|
- **Stream Transfer**:
|
|
44
46
|
|
|
@@ -54,6 +56,8 @@ communication patterns with optional type safety:
|
|
|
54
56
|
pattern allows to transfer arbitrary amounts of arbitrary data by
|
|
55
57
|
chunking the data via a stream.
|
|
56
58
|
|
|
59
|
+

|
|
60
|
+
|
|
57
61
|
- **Service Call**:
|
|
58
62
|
|
|
59
63
|
Service Call is a *bi-directional* communication pattern.
|
|
@@ -69,14 +73,27 @@ communication patterns with optional type safety:
|
|
|
69
73
|
Procedure Call](https://en.wikipedia.org/wiki/Remote_procedure_call)
|
|
70
74
|
(RPC) style communication.
|
|
71
75
|
|
|
76
|
+

|
|
77
|
+
|
|
78
|
+
- **Resource Transfer**:
|
|
79
|
+
|
|
80
|
+
Resource Transfer is a *bi-directional* communication pattern.
|
|
81
|
+
A Resource is the combination of a resource name and optionally zero or more arguments.
|
|
82
|
+
You *provision* for a resource transfer.
|
|
83
|
+
When a resource is *fetched* or *pushed*, a single particular provisioner (in case
|
|
84
|
+
of a directed resource transfer) or one arbitrary provisioner is called and
|
|
85
|
+
sends or receives the resource and its arguments.
|
|
86
|
+
|
|
87
|
+

|
|
88
|
+
|
|
72
89
|
> [!Note]
|
|
73
90
|
> **MQTT+** is similar to and derived from
|
|
74
91
|
> [MQTT-JSON-RPC](https://github.com/rse/mqtt-json-rpc) of the same
|
|
75
92
|
> author, but instead of just JSON, MQTT+ encodes packets as JSON
|
|
76
93
|
> or CBOR (default), uses an own packet format (allowing sender and
|
|
77
94
|
> receiver information), uses shorter NanoIDs instead of longer UUIDs
|
|
78
|
-
> for identification of sender, receiver and requests, and
|
|
79
|
-
>
|
|
95
|
+
> for identification of sender, receiver and requests, and additionally
|
|
96
|
+
> provides stream transfer and resource transfer support.
|
|
80
97
|
|
|
81
98
|
Usage
|
|
82
99
|
-----
|
|
@@ -91,9 +108,10 @@ pattern of each endpoint:
|
|
|
91
108
|
import type * as MQTTpt from "mqtt-plus"
|
|
92
109
|
|
|
93
110
|
export type API = {
|
|
94
|
-
"example/sample":
|
|
95
|
-
"example/upload":
|
|
96
|
-
"example/hello":
|
|
111
|
+
"example/sample": MQTTpt.Event<(a1: string, a2: number) => void>
|
|
112
|
+
"example/upload": MQTTpt.Stream<(name: string) => void>
|
|
113
|
+
"example/hello": MQTTpt.Service<(a1: string, a2: number) => string>
|
|
114
|
+
"example/resource": MQTTpt.Resource<(filename: string) => void>
|
|
97
115
|
}
|
|
98
116
|
```
|
|
99
117
|
|
|
@@ -113,11 +131,11 @@ const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
|
113
131
|
const mqttp = new MQTTp<API>(mqtt)
|
|
114
132
|
|
|
115
133
|
mqtt.on("connect", async () => {
|
|
116
|
-
mqttp.subscribe("example/sample", (a1, a2) => {
|
|
117
|
-
console.log("example/sample:
|
|
134
|
+
await mqttp.subscribe("example/sample", (a1, a2, info) => {
|
|
135
|
+
console.log("example/sample:", a1, a2, "from:", info.sender)
|
|
118
136
|
})
|
|
119
|
-
mqttp.register("example/hello", (a1, a2) => {
|
|
120
|
-
console.log("example/hello:
|
|
137
|
+
await mqttp.register("example/hello", (a1, a2, info) => {
|
|
138
|
+
console.log("example/hello:", a1, a2, "from:", info.sender)
|
|
121
139
|
return `${a1}:${a2}`
|
|
122
140
|
})
|
|
123
141
|
})
|
|
@@ -134,9 +152,9 @@ const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
|
134
152
|
const mqttp = new MQTTp<API>(mqtt)
|
|
135
153
|
|
|
136
154
|
mqtt.on("connect", () => {
|
|
137
|
-
mqttp.emit("example/sample", "
|
|
155
|
+
mqttp.emit("example/sample", "world", 42)
|
|
138
156
|
mqttp.call("example/hello", "world", 42).then((response) => {
|
|
139
|
-
console.log("example/hello response:
|
|
157
|
+
console.log("example/hello response:", response)
|
|
140
158
|
mqtt.end()
|
|
141
159
|
})
|
|
142
160
|
})
|
|
@@ -152,18 +170,12 @@ The **MQTT+** API provides the following methods:
|
|
|
152
170
|
constructor<API>(
|
|
153
171
|
mqtt: MqttClient,
|
|
154
172
|
options?: {
|
|
155
|
-
id:
|
|
156
|
-
codec:
|
|
157
|
-
timeout:
|
|
158
|
-
chunkSize:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
topicServiceRequestMake: (topic: string) => TopicMatching | null
|
|
162
|
-
topicServiceResponseMake: (topic: string) => TopicMatching | null
|
|
163
|
-
topicEventNoticeMatch: { name: string, peerId?: string }
|
|
164
|
-
topicStreamChunkMatch: { name: string, peerId?: string }
|
|
165
|
-
topicServiceRequestMatch: { name: string, peerId?: string }
|
|
166
|
-
topicServiceResponseMatch: { name: string, peerId?: string }
|
|
173
|
+
id: string
|
|
174
|
+
codec: "cbor" | "json"
|
|
175
|
+
timeout: number
|
|
176
|
+
chunkSize: number
|
|
177
|
+
topicMake: (name: string, operation: string, peerId?: string) => string
|
|
178
|
+
topicMatch: (topic: string) => { name: string, operation: string, peerId?: string } | null
|
|
167
179
|
}
|
|
168
180
|
)
|
|
169
181
|
|
|
@@ -180,22 +192,12 @@ The **MQTT+** API provides the following methods:
|
|
|
180
192
|
- `codec`: Encoding format (default: `cbor`).
|
|
181
193
|
- `timeout`: Communication timeout in milliseconds (default: `10000`).
|
|
182
194
|
- `chunkSize`: Chunk size in bytes for stream transfers (default: `16384`).
|
|
183
|
-
- `
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
(default: `` (
|
|
189
|
-
- `topicServiceResponseMake`): Custom topic generation for service responses.
|
|
190
|
-
(default: `` (name, peerId) => peerId ? `${name}/service-response/${peerId}` : `${name}/service-response` ``)
|
|
191
|
-
- `topicEventNoticeMatch`: Custom topic matching for event notices.
|
|
192
|
-
(default: `` (topic) => { const m = topic.match(/^(.+?)\/event-notice(?:\/(.+))?$/); return m ? { name: m[1], peerId: m[2] } : null } ``)
|
|
193
|
-
- `topicStreamChunkMatch`: Custom topic matching for stream chunks.
|
|
194
|
-
(default: `` (topic) => { const m = topic.match(/^(.+?)\/stream-chunk(?:\/(.+))?$/); return m ? { name: m[1], peerId: m[2] } : null } ``)
|
|
195
|
-
- `topicServiceRequestMatch`: Custom topic matching for service requests.
|
|
196
|
-
(default: `` (topic) => { const m = topic.match(/^(.+?)\/service-request(?:\/(.+))?$/); return m ? { name: m[1], peerId: m[2] } : null } ``)
|
|
197
|
-
- `topicServiceResponseMatch`: Custom topic matching for service responses.
|
|
198
|
-
(default: `` (topic) => { const m = topic.match(/^(.+?)\/service-response\/(.+)$/); return m ? { name: m[1], peerId: m[2] } : null } ``)
|
|
195
|
+
- `topicMake`: Custom topic generation function.
|
|
196
|
+
The `operation` parameter is one of: `event-emission`, `stream-transfer`, `service-call-request`, `service-call-response`, `resource-transfer-request`, `resource-transfer-response`.
|
|
197
|
+
(default: `` (name, operation, peerId) => `${name}/${operation}` + (peerId ? `/${peerId}` : "/any") ``)
|
|
198
|
+
- `topicMatch`: Custom topic matching function.
|
|
199
|
+
Returns `{ name, operation, peerId? }` or `null` if no match. The `peerId` is `undefined` for broadcast topics (ending with `/any`).
|
|
200
|
+
(default: `` (topic) => { const m = topic.match(/^(.+)\/([^/]+)\/([^/]+)$/); return m ? { name: m[1], operation: m[2], peerId: m[3] === "any" ? undefined : m[3] } : null } ``)
|
|
199
201
|
|
|
200
202
|
- **Event Subscription**:<br/>
|
|
201
203
|
|
|
@@ -216,8 +218,8 @@ The **MQTT+** API provides the following methods:
|
|
|
216
218
|
There is no return value of `callback`.
|
|
217
219
|
|
|
218
220
|
Internally, on the MQTT broker, the topics generated by
|
|
219
|
-
`
|
|
220
|
-
`${event}/event-
|
|
221
|
+
`topicMake(event, "event-emission")` (default: `${event}/event-emission/any` and
|
|
222
|
+
`${event}/event-emission/${peerId}`) are subscribed. Returns a
|
|
221
223
|
`Subscription` object with an `unsubscribe()` method.
|
|
222
224
|
|
|
223
225
|
- **Stream Attachment**:<br/>
|
|
@@ -240,8 +242,8 @@ The **MQTT+** API provides the following methods:
|
|
|
240
242
|
There is no return value of `callback`.
|
|
241
243
|
|
|
242
244
|
Internally, on the MQTT broker, the topics generated by
|
|
243
|
-
`
|
|
244
|
-
`${stream}/stream-
|
|
245
|
+
`topicMake(stream, "stream-transfer")` (default: `${stream}/stream-transfer/any` and
|
|
246
|
+
`${stream}/stream-transfer/${peerId}`) are subscribed. Returns an
|
|
245
247
|
`Attachment` object with an `unattach()` method.
|
|
246
248
|
|
|
247
249
|
- **Service Registration**:<br/>
|
|
@@ -263,10 +265,33 @@ The **MQTT+** API provides the following methods:
|
|
|
263
265
|
The return value of `callback` will resolve the `Promise` returned by the remote `call()`.
|
|
264
266
|
|
|
265
267
|
Internally, on the MQTT broker, the topics by
|
|
266
|
-
`
|
|
267
|
-
`${service}/service-request/${peerId}`) are subscribed. Returns a
|
|
268
|
+
`topicMake(service, "service-call-request")` (default: `${service}/service-call-request/any` and
|
|
269
|
+
`${service}/service-call-request/${peerId}`) are subscribed. Returns a
|
|
268
270
|
`Registration` object with an `unregister()` method.
|
|
269
271
|
|
|
272
|
+
- **Resource Provisioning**:<br/>
|
|
273
|
+
|
|
274
|
+
/* (simplified TypeScript API method signature) */
|
|
275
|
+
provision(
|
|
276
|
+
resource: string,
|
|
277
|
+
options?: MQTT::IClientSubscribeOptions
|
|
278
|
+
callback: (
|
|
279
|
+
...params: any[],
|
|
280
|
+
info: { sender: string, receiver?: string, resource: Buffer | null }
|
|
281
|
+
) => void
|
|
282
|
+
): Promise<Provisioning>
|
|
283
|
+
|
|
284
|
+
Provision a resource.
|
|
285
|
+
The `resource` has to be a valid MQTT topic name.
|
|
286
|
+
The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
287
|
+
The `callback` is called with the `params` passed to a remote `fetch()`.
|
|
288
|
+
The `callback` should set `info.resource` to a `Buffer` containing the resource data.
|
|
289
|
+
|
|
290
|
+
Internally, on the MQTT broker, the topics by
|
|
291
|
+
`topicMake(resource, "resource-transfer-request")` (default: `${resource}/resource-transfer-request/any` and
|
|
292
|
+
`${resource}/resource-transfer-request/${peerId}`) are subscribed. Returns a
|
|
293
|
+
`Provisioning` object with an `unprovision()` method.
|
|
294
|
+
|
|
270
295
|
- **Event Emission**:<br/>
|
|
271
296
|
|
|
272
297
|
/* (simplified TypeScript API method signature) */
|
|
@@ -284,8 +309,8 @@ The **MQTT+** API provides the following methods:
|
|
|
284
309
|
The remote `subscribe()` `callback` is called with `params` and its
|
|
285
310
|
return value is silently ignored.
|
|
286
311
|
|
|
287
|
-
Internally, publishes to the MQTT topic by `
|
|
288
|
-
(default: `${event}/event-
|
|
312
|
+
Internally, publishes to the MQTT topic by `topicMake(event, "event-emission", peerId)`
|
|
313
|
+
(default: `${event}/event-emission/any` or `${event}/event-emission/${peerId}`).
|
|
289
314
|
|
|
290
315
|
- **Stream Transfer**:<br/>
|
|
291
316
|
|
|
@@ -311,8 +336,8 @@ The **MQTT+** API provides the following methods:
|
|
|
311
336
|
The remote `attach()` `callback` is called with `params` and an `info` object
|
|
312
337
|
containing a `stream.Readable` for consuming the transferred data.
|
|
313
338
|
|
|
314
|
-
Internally, publishes to the MQTT topic by `
|
|
315
|
-
(default: `${stream}/stream-
|
|
339
|
+
Internally, publishes to the MQTT topic by `topicMake(stream, "stream-transfer", peerId)`
|
|
340
|
+
(default: `${stream}/stream-transfer/any` or `${stream}/stream-transfer/${peerId}`).
|
|
316
341
|
|
|
317
342
|
- **Service Call**:<br/>
|
|
318
343
|
|
|
@@ -332,8 +357,31 @@ The **MQTT+** API provides the following methods:
|
|
|
332
357
|
return value resolves the returned `Promise`. If the remote `callback`
|
|
333
358
|
throws an exception, this rejects the returned `Promise`.
|
|
334
359
|
|
|
335
|
-
Internally, on the MQTT broker, the topic by `
|
|
336
|
-
(default: `${service}/service-response/${peerId}`) is temporarily subscribed
|
|
360
|
+
Internally, on the MQTT broker, the topic by `topicMake(service, "service-call-response", peerId)`
|
|
361
|
+
(default: `${service}/service-call-response/${peerId}`) is temporarily subscribed
|
|
362
|
+
for receiving the response.
|
|
363
|
+
|
|
364
|
+
- **Resource Transfer**:<br/>
|
|
365
|
+
|
|
366
|
+
/* (simplified TypeScript API method signature) */
|
|
367
|
+
fetch(
|
|
368
|
+
blob: string,
|
|
369
|
+
receiver?: Receiver,
|
|
370
|
+
options?: MQTT::IClientSubscribeOptions,
|
|
371
|
+
...params: any[]
|
|
372
|
+
): Promise<Buffer>
|
|
373
|
+
|
|
374
|
+
Fetches a resource from any resource provisioner or from a specific provisioner.
|
|
375
|
+
The optional `receiver` directs the call to a specific provisioner only.
|
|
376
|
+
The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
377
|
+
|
|
378
|
+
The remote `provision()` `callback` is called with `params` and its
|
|
379
|
+
return value resolves the returned `Promise`. If the remote `callback`
|
|
380
|
+
throws an exception, this rejects the returned `Promise`.
|
|
381
|
+
|
|
382
|
+
Internally, on the MQTT broker, the topic by
|
|
383
|
+
`topicMake(resource, "resource-transfer-response", peerId)` (default:
|
|
384
|
+
`${resource}/resource-transfer-response/${peerId}`) is temporarily subscribed
|
|
337
385
|
for receiving the response.
|
|
338
386
|
|
|
339
387
|
- **Receiver Wrapping**:<br/>
|
|
@@ -368,15 +416,16 @@ mqttp.call("example/hello", "world", 42).then((result) => {
|
|
|
368
416
|
```
|
|
369
417
|
|
|
370
418
|
...the following message is sent to the permanent MQTT topic
|
|
371
|
-
`example/hello/service-request` (the shown NanoIDs are just
|
|
372
|
-
ones):
|
|
419
|
+
`example/hello/service-call-request/any` (the shown NanoIDs are just
|
|
420
|
+
pseudo ones):
|
|
373
421
|
|
|
374
422
|
```json
|
|
375
423
|
{
|
|
424
|
+
"type": "service-call-request",
|
|
376
425
|
"id": "vwLzfQDu2uEeOdOfIlT42",
|
|
377
|
-
"
|
|
378
|
-
"
|
|
379
|
-
"
|
|
426
|
+
"service": "example/hello",
|
|
427
|
+
"params": [ "world", 42 ],
|
|
428
|
+
"sender": "2IBMSk0NPnrz1AeTERoea"
|
|
380
429
|
}
|
|
381
430
|
```
|
|
382
431
|
|
|
@@ -391,13 +440,15 @@ mqttp.register("example/hello", (a1, a2) => {
|
|
|
391
440
|
...and then its result, in the above `mqttp.call()` example `"world:42"`, is then
|
|
392
441
|
sent back as the following success response
|
|
393
442
|
message to the temporary (client-specific) MQTT topic
|
|
394
|
-
`example/hello/service-response/2IBMSk0NPnrz1AeTERoea`:
|
|
443
|
+
`example/hello/service-call-response/2IBMSk0NPnrz1AeTERoea`:
|
|
395
444
|
|
|
396
445
|
```json
|
|
397
446
|
{
|
|
398
|
-
"
|
|
399
|
-
"
|
|
400
|
-
"result":
|
|
447
|
+
"type": "service-call-response",
|
|
448
|
+
"id": "vwLzfQDu2uEeOdOfIlT42",
|
|
449
|
+
"result": "world:42",
|
|
450
|
+
"sender": "2IBMSk0NPnrz1AeTERoea",
|
|
451
|
+
"receiver": "2IBMSk0NPnrz1AeTERoea"
|
|
401
452
|
}
|
|
402
453
|
```
|
|
403
454
|
|
|
@@ -503,18 +554,18 @@ mqtt.on("close", () => { console.log("CLOSE") })
|
|
|
503
554
|
mqtt.on("reconnect", () => { console.log("RECONNECT") })
|
|
504
555
|
mqtt.on("message", (topic, message) => { console.log("RECEIVED", topic, message.toString()) })
|
|
505
556
|
|
|
506
|
-
mqtt.on("connect", () => {
|
|
557
|
+
mqtt.on("connect", async () => {
|
|
507
558
|
console.log("CONNECT")
|
|
508
|
-
mqttp.register("example/hello", (a1, a2) => {
|
|
509
|
-
console.log("example/hello: request:
|
|
559
|
+
await mqttp.register("example/hello", (a1, a2, info) => {
|
|
560
|
+
console.log("example/hello: request:", a1, a2, "from:", info.sender)
|
|
510
561
|
return `${a1}:${a2}`
|
|
511
562
|
})
|
|
512
|
-
mqttp.call("example/hello", "world", 42).then((result) => {
|
|
513
|
-
console.log("example/hello success:
|
|
563
|
+
mqttp.call("example/hello", "world", 42).then(async (result) => {
|
|
564
|
+
console.log("example/hello success:", result)
|
|
514
565
|
mqtt.end()
|
|
515
566
|
await mosquitto.stop()
|
|
516
567
|
}).catch((err) => {
|
|
517
|
-
console.log("example/hello error:
|
|
568
|
+
console.log("example/hello error:", err)
|
|
518
569
|
})
|
|
519
570
|
})
|
|
520
571
|
```
|
|
@@ -524,17 +575,17 @@ The output will be:
|
|
|
524
575
|
```
|
|
525
576
|
$ node sample.ts
|
|
526
577
|
CONNECT
|
|
527
|
-
RECEIVED example/hello/service-request {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","service":"example/hello","params":["world",42]}
|
|
528
|
-
example/hello: request:
|
|
529
|
-
RECEIVED example/hello/service-response/2IBMSk0NPnrz1AeTERoea {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","receiver":"2IBMSk0NPnrz1AeTERoea","result":"world:42"}
|
|
530
|
-
example/hello success:
|
|
578
|
+
RECEIVED example/hello/service-call-request/any {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","service":"example/hello","params":["world",42]}
|
|
579
|
+
example/hello: request: world 42 from: 2IBMSk0NPnrz1AeTERoea
|
|
580
|
+
RECEIVED example/hello/service-call-response/2IBMSk0NPnrz1AeTERoea {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","receiver":"2IBMSk0NPnrz1AeTERoea","result":"world:42"}
|
|
581
|
+
example/hello success: world:42
|
|
531
582
|
CLOSE
|
|
532
583
|
```
|
|
533
584
|
|
|
534
585
|
License
|
|
535
586
|
-------
|
|
536
587
|
|
|
537
|
-
Copyright (c) 2018-
|
|
588
|
+
Copyright (c) 2018-2026 Dr. Ralf S. Engelschall (http://engelschall.com/)
|
|
538
589
|
|
|
539
590
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
540
591
|
a copy of this software and associated documentation files (the
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
shape: sequence_diagram
|
|
3
|
+
|
|
4
|
+
client: "Client"
|
|
5
|
+
broker: "Broker"
|
|
6
|
+
server: "Server"
|
|
7
|
+
|
|
8
|
+
broker.class: brown
|
|
9
|
+
|
|
10
|
+
"subscribe(\"foo/bar\")": {
|
|
11
|
+
server -> broker: "op: subscribe\ntopic: foo/bar/event-emission/any"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
"emit(\"foo/bar\")": {
|
|
15
|
+
client -> broker: "op: publish\ntopic: foo/bar/event-emission/any\ndata: Event-Emission"
|
|
16
|
+
broker -> server: "op: publish\ntopic: foo/bar/event-emission/any\ndata: Event-Emission"
|
|
17
|
+
}
|
|
18
|
+
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-d2-version="v0.7.0-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 670 524"><svg class="d2-1243767131 d2-svg" width="670" height="524" viewBox="11 51 670 524"><rect x="11.000000" y="51.000000" width="670.000000" height="524.000000" rx="0.000000" fill="#ffffff" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
|
|
2
|
+
.d2-1243767131 .text {
|
|
3
|
+
font-family: "d2-1243767131-font-regular";
|
|
4
|
+
}
|
|
5
|
+
@font-face {
|
|
6
|
+
font-family: d2-1243767131-font-regular;
|
|
7
|
+
src: url("data:application/font-woff;base64,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");
|
|
8
|
+
}
|
|
9
|
+
.d2-1243767131 .text-italic {
|
|
10
|
+
font-family: "d2-1243767131-font-italic";
|
|
11
|
+
}
|
|
12
|
+
@font-face {
|
|
13
|
+
font-family: d2-1243767131-font-italic;
|
|
14
|
+
src: url("data:application/font-woff;base64,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");
|
|
15
|
+
}]]></style><style type="text/css"><![CDATA[.shape {
|
|
16
|
+
shape-rendering: geometricPrecision;
|
|
17
|
+
stroke-linejoin: round;
|
|
18
|
+
}
|
|
19
|
+
.connection {
|
|
20
|
+
stroke-linecap: round;
|
|
21
|
+
stroke-linejoin: round;
|
|
22
|
+
}
|
|
23
|
+
.blend {
|
|
24
|
+
mix-blend-mode: multiply;
|
|
25
|
+
opacity: 0.5;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.d2-1243767131 .fill-N1{fill:#303030;}
|
|
29
|
+
.d2-1243767131 .fill-N2{fill:#606060;}
|
|
30
|
+
.d2-1243767131 .fill-N3{fill:#909090;}
|
|
31
|
+
.d2-1243767131 .fill-N4{fill:#c0c0c0;}
|
|
32
|
+
.d2-1243767131 .fill-N5{fill:#e0e0e0;}
|
|
33
|
+
.d2-1243767131 .fill-N6{fill:#f0f0f0;}
|
|
34
|
+
.d2-1243767131 .fill-N7{fill:#ffffff;}
|
|
35
|
+
.d2-1243767131 .fill-B1{fill:#336699;}
|
|
36
|
+
.d2-1243767131 .fill-B2{fill:#6699cc;}
|
|
37
|
+
.d2-1243767131 .fill-B3{fill:#99ccff;}
|
|
38
|
+
.d2-1243767131 .fill-B4{fill:#c0d0ff;}
|
|
39
|
+
.d2-1243767131 .fill-B5{fill:#e0f0ff;}
|
|
40
|
+
.d2-1243767131 .fill-B6{fill:#f0f8ff;}
|
|
41
|
+
.d2-1243767131 .fill-AA2{fill:#cfb098;}
|
|
42
|
+
.d2-1243767131 .fill-AA4{fill:#efd0b8;}
|
|
43
|
+
.d2-1243767131 .fill-AA5{fill:#ffe0c8;}
|
|
44
|
+
.d2-1243767131 .fill-AB4{fill:#efd0b8;}
|
|
45
|
+
.d2-1243767131 .fill-AB5{fill:#ffe0c8;}
|
|
46
|
+
.d2-1243767131 .stroke-N1{stroke:#303030;}
|
|
47
|
+
.d2-1243767131 .stroke-N2{stroke:#606060;}
|
|
48
|
+
.d2-1243767131 .stroke-N3{stroke:#909090;}
|
|
49
|
+
.d2-1243767131 .stroke-N4{stroke:#c0c0c0;}
|
|
50
|
+
.d2-1243767131 .stroke-N5{stroke:#e0e0e0;}
|
|
51
|
+
.d2-1243767131 .stroke-N6{stroke:#f0f0f0;}
|
|
52
|
+
.d2-1243767131 .stroke-N7{stroke:#ffffff;}
|
|
53
|
+
.d2-1243767131 .stroke-B1{stroke:#336699;}
|
|
54
|
+
.d2-1243767131 .stroke-B2{stroke:#6699cc;}
|
|
55
|
+
.d2-1243767131 .stroke-B3{stroke:#99ccff;}
|
|
56
|
+
.d2-1243767131 .stroke-B4{stroke:#c0d0ff;}
|
|
57
|
+
.d2-1243767131 .stroke-B5{stroke:#e0f0ff;}
|
|
58
|
+
.d2-1243767131 .stroke-B6{stroke:#f0f8ff;}
|
|
59
|
+
.d2-1243767131 .stroke-AA2{stroke:#cfb098;}
|
|
60
|
+
.d2-1243767131 .stroke-AA4{stroke:#efd0b8;}
|
|
61
|
+
.d2-1243767131 .stroke-AA5{stroke:#ffe0c8;}
|
|
62
|
+
.d2-1243767131 .stroke-AB4{stroke:#efd0b8;}
|
|
63
|
+
.d2-1243767131 .stroke-AB5{stroke:#ffe0c8;}
|
|
64
|
+
.d2-1243767131 .background-color-N1{background-color:#303030;}
|
|
65
|
+
.d2-1243767131 .background-color-N2{background-color:#606060;}
|
|
66
|
+
.d2-1243767131 .background-color-N3{background-color:#909090;}
|
|
67
|
+
.d2-1243767131 .background-color-N4{background-color:#c0c0c0;}
|
|
68
|
+
.d2-1243767131 .background-color-N5{background-color:#e0e0e0;}
|
|
69
|
+
.d2-1243767131 .background-color-N6{background-color:#f0f0f0;}
|
|
70
|
+
.d2-1243767131 .background-color-N7{background-color:#ffffff;}
|
|
71
|
+
.d2-1243767131 .background-color-B1{background-color:#336699;}
|
|
72
|
+
.d2-1243767131 .background-color-B2{background-color:#6699cc;}
|
|
73
|
+
.d2-1243767131 .background-color-B3{background-color:#99ccff;}
|
|
74
|
+
.d2-1243767131 .background-color-B4{background-color:#c0d0ff;}
|
|
75
|
+
.d2-1243767131 .background-color-B5{background-color:#e0f0ff;}
|
|
76
|
+
.d2-1243767131 .background-color-B6{background-color:#f0f8ff;}
|
|
77
|
+
.d2-1243767131 .background-color-AA2{background-color:#cfb098;}
|
|
78
|
+
.d2-1243767131 .background-color-AA4{background-color:#efd0b8;}
|
|
79
|
+
.d2-1243767131 .background-color-AA5{background-color:#ffe0c8;}
|
|
80
|
+
.d2-1243767131 .background-color-AB4{background-color:#efd0b8;}
|
|
81
|
+
.d2-1243767131 .background-color-AB5{background-color:#ffe0c8;}
|
|
82
|
+
.d2-1243767131 .color-N1{color:#303030;}
|
|
83
|
+
.d2-1243767131 .color-N2{color:#606060;}
|
|
84
|
+
.d2-1243767131 .color-N3{color:#909090;}
|
|
85
|
+
.d2-1243767131 .color-N4{color:#c0c0c0;}
|
|
86
|
+
.d2-1243767131 .color-N5{color:#e0e0e0;}
|
|
87
|
+
.d2-1243767131 .color-N6{color:#f0f0f0;}
|
|
88
|
+
.d2-1243767131 .color-N7{color:#ffffff;}
|
|
89
|
+
.d2-1243767131 .color-B1{color:#336699;}
|
|
90
|
+
.d2-1243767131 .color-B2{color:#6699cc;}
|
|
91
|
+
.d2-1243767131 .color-B3{color:#99ccff;}
|
|
92
|
+
.d2-1243767131 .color-B4{color:#c0d0ff;}
|
|
93
|
+
.d2-1243767131 .color-B5{color:#e0f0ff;}
|
|
94
|
+
.d2-1243767131 .color-B6{color:#f0f8ff;}
|
|
95
|
+
.d2-1243767131 .color-AA2{color:#cfb098;}
|
|
96
|
+
.d2-1243767131 .color-AA4{color:#efd0b8;}
|
|
97
|
+
.d2-1243767131 .color-AA5{color:#ffe0c8;}
|
|
98
|
+
.d2-1243767131 .color-AB4{color:#efd0b8;}
|
|
99
|
+
.d2-1243767131 .color-AB5{color:#ffe0c8;}.appendix text.text{fill:#303030}.md{--color-fg-default:#303030;--color-fg-muted:#606060;--color-fg-subtle:#909090;--color-canvas-default:#ffffff;--color-canvas-subtle:#f0f0f0;--color-border-default:#336699;--color-border-muted:#6699cc;--color-neutral-muted:#f0f0f0;--color-accent-fg:#6699cc;--color-accent-emphasis:#6699cc;--color-attention-subtle:#606060;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-dark-d2-1243767131);mix-blend-mode:overlay}.sketch-overlay-B2{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-B3{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-B4{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-AA4{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1243767131);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1243767131);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]></style><g class="Y2xpZW50"><g class="shape" ><rect x="12.000000" y="52.000000" width="100.000000" height="66.000000" stroke="#336699" fill="#e0f0ff" class=" stroke-B1 fill-B5" style="stroke-width:2;" /></g><text x="62.000000" y="90.500000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">Client</text></g><g class="YnJva2Vy brown"><g class="shape" ><rect x="296.000000" y="52.000000" width="100.000000" height="66.000000" stroke="#cfb098" fill="#ffe0c9" style="stroke-width:2;" /></g><text x="346.000000" y="90.500000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">Broker</text></g><g class="c2VydmVy"><g class="shape" ><rect x="580.000000" y="52.000000" width="100.000000" height="66.000000" stroke="#336699" fill="#e0f0ff" class=" stroke-B1 fill-B5" style="stroke-width:2;" /></g><text x="630.000000" y="90.500000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">Server</text></g><g class="KGNsaWVudCAtLSApWzBd"><path d="M 62.000000 120.000000 L 62.000000 573.000000" stroke="#6699cc" fill="none" class="connection stroke-B2" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1243767131)" /></g><g class="KGJyb2tlciAtLSApWzBd"><path d="M 346.000000 120.000000 L 346.000000 573.000000" stroke="#cfb098" fill="none" class="connection" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1243767131)" /></g><g class="KHNlcnZlciAtLSApWzBd"><path d="M 630.000000 120.000000 L 630.000000 573.000000" stroke="#6699cc" fill="none" class="connection stroke-B2" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1243767131)" /></g><g class="JiMzOTtzdWJzY3JpYmUoJiMzNDtmb28vYmFyJiMzNDspJiMzOTs="><g class="shape blend" ><rect x="306.000000" y="175.000000" width="364.000000" height="92.000000" stroke="#336699" fill="#e0e0e0" class=" stroke-B1 fill-N5" style="stroke-width:0;" /></g><rect x="311.000000" y="180.000000" width="138.000000" height="21.000000" fill="#e0e0e0" class=" fill-N5" /><text x="380.000000" y="196.000000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">subscribe("foo/bar")</text></g><g class="JiMzOTtlbWl0KCYjMzQ7Zm9vL2JhciYjMzQ7KSYjMzk7"><g class="shape blend" ><rect x="22.000000" y="312.000000" width="648.000000" height="230.000000" stroke="#336699" fill="#e0e0e0" class=" stroke-B1 fill-N5" style="stroke-width:0;" /></g><rect x="27.000000" y="317.000000" width="104.000000" height="21.000000" fill="#e0e0e0" class=" fill-N5" /><text x="79.000000" y="333.000000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">emit("foo/bar")</text></g><g class="KHNlcnZlciAtJmd0OyBicm9rZXIpWzBd"><marker id="mk-d2-1243767131-3488378134" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" fill="#336699" class="connection fill-B1" stroke-width="2" /> </marker><path d="M 628.000000 237.000000 L 350.000000 237.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1243767131-3488378134)" mask="url(#d2-1243767131)" /><text x="488.000000" y="235.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="488.000000" dy="0.000000">op: subscribe</tspan><tspan x="488.000000" dy="18.500000">topic: foo/bar/event-emission/any</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzBd"><path d="M 64.000000 382.000000 L 342.000000 382.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1243767131-3488378134)" mask="url(#d2-1243767131)" /><text x="204.000000" y="372.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="204.000000" dy="0.000000">op: publish</tspan><tspan x="204.000000" dy="17.666667">topic: foo/bar/event-emission/any</tspan><tspan x="204.000000" dy="17.666667">data: Event-Emission</tspan></text></g><g class="KGJyb2tlciAtJmd0OyBzZXJ2ZXIpWzBd"><path d="M 348.000000 504.000000 L 626.000000 504.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1243767131-3488378134)" mask="url(#d2-1243767131)" /><text x="488.000000" y="494.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="488.000000" dy="0.000000">op: publish</tspan><tspan x="488.000000" dy="17.666667">topic: foo/bar/event-emission/any</tspan><tspan x="488.000000" dy="17.666667">data: Event-Emission</tspan></text></g><mask id="d2-1243767131" maskUnits="userSpaceOnUse" x="11" y="51" width="670" height="524">
|
|
100
|
+
<rect x="11" y="51" width="670" height="524" fill="white"></rect>
|
|
101
|
+
<rect x="374.000000" y="219.000000" width="228" height="37" fill="black"></rect>
|
|
102
|
+
<rect x="90.000000" y="356.000000" width="228" height="53" fill="black"></rect>
|
|
103
|
+
<rect x="374.000000" y="478.000000" width="228" height="53" fill="black"></rect>
|
|
104
|
+
</mask></svg></svg>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
shape: sequence_diagram
|
|
3
|
+
|
|
4
|
+
client: "Client"
|
|
5
|
+
broker: "Broker"
|
|
6
|
+
server: "Server"
|
|
7
|
+
|
|
8
|
+
broker.class: brown
|
|
9
|
+
|
|
10
|
+
attach("foo/bar") {
|
|
11
|
+
server -> broker: "op: subscribe\ntopic: foo/bar/stream-transfer"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
fetch("foo/bar") {
|
|
15
|
+
client -> broker: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer #1"
|
|
16
|
+
broker -> server: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer #1"
|
|
17
|
+
client -> broker: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer #N"
|
|
18
|
+
broker -> server: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer #N"
|
|
19
|
+
client -> broker: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer EoS"
|
|
20
|
+
broker -> server: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer EoS"
|
|
21
|
+
}
|
|
22
|
+
|