mqtt-json-rpc 2.1.1 → 3.0.1
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 +259 -95
- package/dst/mqtt-json-rpc.cjs.js +6425 -4940
- package/dst/mqtt-json-rpc.d.ts +54 -20
- package/dst/mqtt-json-rpc.esm.js +6425 -4940
- package/dst/mqtt-json-rpc.js +377 -183
- package/dst/mqtt-json-rpc.umd.js +19 -10
- package/etc/eslint.mts +11 -46
- package/etc/logo.svg +19 -0
- package/etc/stx.conf +2 -2
- package/etc/vite.mts +4 -1
- package/package.json +10 -8
- package/src/mqtt-json-rpc.ts +527 -224
- package/sample/package.json +0 -23
- package/sample/sample.html +0 -11
- package/sample/sample.js +0 -26
- package/sample/sample.ts +0 -34
- package/sample/tsc.json +0 -26
- package/sample/tsc.tsbuildinfo +0 -1
- package/sample/vite.mjs +0 -36
package/README.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
|
|
2
|
+
<img src="https://raw.githubusercontent.com/rse/mqtt-json-rpc/master/etc/logo.svg" width="300" align="right" alt=""/>
|
|
3
|
+
|
|
2
4
|
MQTT-JSON-RPC
|
|
3
5
|
=============
|
|
4
6
|
|
|
@@ -7,8 +9,18 @@ MQTT-JSON-RPC
|
|
|
7
9
|
<p/>
|
|
8
10
|
<img src="https://nodei.co/npm/mqtt-json-rpc.png?downloads=true&stars=true" alt=""/>
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
[](https://github.com/rse)
|
|
13
|
+
[](https://github.com/rse)
|
|
14
|
+
|
|
15
|
+
> [!Note]
|
|
16
|
+
> This package is no longer actively developed, as it
|
|
17
|
+
> already evolved into a more sophisticated solution named
|
|
18
|
+
> [**MQTT+**](https://github.com/rse/mqtt-plus). **MQTT+**
|
|
19
|
+
> encodes packets as CBOR by default, uses an own packet format
|
|
20
|
+
> (allowing sender and receiver information), uses shorter NanoIDs
|
|
21
|
+
> instead of longer UUIDs for identification of sender, receiver and
|
|
22
|
+
> requests, and additionally provides bi-directional resource transfer
|
|
23
|
+
> via chunk streaming.
|
|
12
24
|
|
|
13
25
|
Installation
|
|
14
26
|
------------
|
|
@@ -20,44 +32,81 @@ $ npm install mqtt mqtt-json-rpc
|
|
|
20
32
|
About
|
|
21
33
|
-----
|
|
22
34
|
|
|
23
|
-
This is an addon API for the
|
|
24
|
-
[MQTT.js](https://www.npmjs.com/package/mqtt) API
|
|
25
|
-
[
|
|
26
|
-
[Remote Procedure Call](https://en.wikipedia.org/wiki/Remote_procedure_call) (RPC)
|
|
35
|
+
This is an addon API for the excellent
|
|
36
|
+
[MQTT.js](https://www.npmjs.com/package/mqtt) JavaScript/TypeScript API
|
|
37
|
+
for [Remote Procedure Call](https://en.wikipedia.org/wiki/Remote_procedure_call) (RPC)
|
|
27
38
|
communication based on the [JSON-RPC](http://www.jsonrpc.org/)
|
|
28
39
|
protocol. This allows a bi-directional request/response-style communication over
|
|
29
40
|
the technically uni-directional message protocol [MQTT](http://mqtt.org).
|
|
30
41
|
|
|
42
|
+
Conceptually, this RPC API provides two types of communication patterns:
|
|
43
|
+
|
|
44
|
+
- **Event Emission**:
|
|
45
|
+
Event Emission is a *uni-directional* communication pattern.
|
|
46
|
+
An Event is the combination of an event name and optionally zero or more arguments.
|
|
47
|
+
You *subscribe* to events.
|
|
48
|
+
When an event is *emitted*, either a single particular subscriber (in case of
|
|
49
|
+
a directed event emission) or all subscribers are called and receive the
|
|
50
|
+
arguments as extra information.
|
|
51
|
+
|
|
52
|
+
- **Service Call**:
|
|
53
|
+
Service Call is a *bi-directional* communication pattern.
|
|
54
|
+
A Service is the combination of a service name and optionally zero or more arguments.
|
|
55
|
+
You *register* for a service.
|
|
56
|
+
When a service is *called*, a single particular registrator (in case
|
|
57
|
+
of a directed service call) or one arbitrary registrator is called and
|
|
58
|
+
receives the arguments as the request. The registrator then has to
|
|
59
|
+
provide the service response.
|
|
60
|
+
|
|
61
|
+
Notice: while the provided Event Emission functionality is just a very thing
|
|
62
|
+
wrapper around the regular MQTT message publishing API of MQTT.js, the
|
|
63
|
+
Service Call functionality is the core and heart of this addon API.
|
|
64
|
+
|
|
31
65
|
Usage
|
|
32
66
|
-----
|
|
33
67
|
|
|
34
|
-
|
|
68
|
+
### API:
|
|
35
69
|
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
70
|
+
```ts
|
|
71
|
+
export type API = {
|
|
72
|
+
"example/sample": (a1: string, a2: boolean) => void
|
|
73
|
+
"example/hello": (a1: string, a2: number) => string
|
|
74
|
+
}
|
|
75
|
+
```
|
|
39
76
|
|
|
40
|
-
|
|
41
|
-
const rpc = new RPC(mqtt)
|
|
77
|
+
### Server:
|
|
42
78
|
|
|
43
|
-
|
|
79
|
+
```ts
|
|
80
|
+
import MQTT from "mqtt"
|
|
81
|
+
import RPC from "mqtt-json-rpc"
|
|
82
|
+
import type { API } from [...]
|
|
83
|
+
|
|
84
|
+
const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
85
|
+
const rpc = new RPC<API>(mqtt)
|
|
86
|
+
|
|
87
|
+
mqtt.on("connect", async () => {
|
|
88
|
+
rpc.subscribe("example/sample", (a1, a2) => {
|
|
89
|
+
console.log("example/sample: ", a1, a2)
|
|
90
|
+
})
|
|
44
91
|
rpc.register("example/hello", (a1, a2) => {
|
|
45
|
-
console.log("example/hello:
|
|
92
|
+
console.log("example/hello: ", a1, a2)
|
|
46
93
|
return `${a1}:${a2}`
|
|
47
94
|
})
|
|
48
95
|
})
|
|
49
96
|
```
|
|
50
97
|
|
|
51
|
-
|
|
98
|
+
### Client:
|
|
52
99
|
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
|
|
100
|
+
```ts
|
|
101
|
+
import MQTT from "mqtt"
|
|
102
|
+
import RPC from "mqtt-json-rpc"
|
|
103
|
+
import type { API } from [...]
|
|
56
104
|
|
|
57
|
-
const mqtt = MQTT.connect("wss://127.0.0.1:
|
|
58
|
-
const rpc = new RPC(mqtt)
|
|
105
|
+
const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
106
|
+
const rpc = new RPC<API>(mqtt)
|
|
59
107
|
|
|
60
108
|
mqtt.on("connect", () => {
|
|
109
|
+
rpc.emit("example/sample", "foo", true)
|
|
61
110
|
rpc.call("example/hello", "world", 42).then((response) => {
|
|
62
111
|
console.log("example/hello response: ", response)
|
|
63
112
|
mqtt.end()
|
|
@@ -68,60 +117,160 @@ mqtt.on("connect", () => {
|
|
|
68
117
|
Application Programming Interface
|
|
69
118
|
---------------------------------
|
|
70
119
|
|
|
71
|
-
The
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
- `
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
- `
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
- `
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
120
|
+
The RPC API provides the following methods:
|
|
121
|
+
|
|
122
|
+
- **Construction**:<br/>
|
|
123
|
+
|
|
124
|
+
constructor(
|
|
125
|
+
mqtt: MqttClient,
|
|
126
|
+
options?: {
|
|
127
|
+
clientId: string
|
|
128
|
+
codec: "cbor" | "json"
|
|
129
|
+
timeout: number
|
|
130
|
+
topicEventNoticeMake: (topic: string) => TopicMatching | null
|
|
131
|
+
topicServiceRequestMake: (topic: string) => TopicMatching | null
|
|
132
|
+
topicServiceResponseMake: (topic: string) => TopicMatching | null
|
|
133
|
+
topicEventNoticeMatch: { name: string, clientId?: string }
|
|
134
|
+
topicServiceRequestMatch: { name: string, clientId?: string }
|
|
135
|
+
topicServiceResponseMatch: { name: string, clientId?: string }
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
The `mqtt` is the [MQTT.js](https://www.npmjs.com/package/mqtt) instance,
|
|
140
|
+
which has to be establish separately.
|
|
141
|
+
The optional `options` object supports the following fields:
|
|
142
|
+
- `clientId`: Custom client identifier (default: auto-generated UUID v1).
|
|
143
|
+
- `codec`: Encoding format (default: `cbor`).
|
|
144
|
+
- `timeout`: Communication timeout in milliseconds (default: `10000`).
|
|
145
|
+
- `topicEventNoticeMake`: Custom topic generation for event notices.
|
|
146
|
+
(default: `` (name, clientId) => clientId ? `${name}/event-notice/${clientId}` : `${name}/event-notice` ``)
|
|
147
|
+
- `topicServiceRequestMake`: Custom topic generation for service requests.
|
|
148
|
+
(default: `` (name, clientId) => clientId ? `${name}/service-request/${clientId}` : `${name}/service-request` ``)
|
|
149
|
+
- `topicServiceResponseMake`): Custom topic generation for service responses.
|
|
150
|
+
(default: `` (name, clientId) => clientId ? `${name}/service-response/${clientId}` : `${name}/service-response` ``)
|
|
151
|
+
- `topicEventNoticeMatch`: Custom topic matching for event notices.
|
|
152
|
+
(default: `` (topic) => { const m = topic.match(/^(.+?)\/event-notice(?:\/(.+))?$/); return m ? { name: m[1], clientId: m[2] } : null } ``)
|
|
153
|
+
- `topicServiceRequestMatch`: Custom topic matching for service requests.
|
|
154
|
+
(default: `` (topic) => { const m = topic.match(/^(.+?)\/service-request(?:\/(.+))?$/); return m ? { name: m[1], clientId: m[2] } : null } ``)
|
|
155
|
+
- `topicServiceResponseMatch`: Custom topic matching for service responses.
|
|
156
|
+
(default: `` (topic) => { const m = topic.match(/^(.+?)\/service-response\/(.+)$/); return m ? { name: m[1], clientId: m[2] } : null } ``)
|
|
157
|
+
|
|
158
|
+
- **Event Subscription**:<br/>
|
|
159
|
+
|
|
160
|
+
/* (simplified TypeScript API method signature) */
|
|
161
|
+
subscribe(
|
|
162
|
+
event: string,
|
|
163
|
+
options?: MQTT::IClientSubscribeOptions
|
|
164
|
+
callback: (...params: any[]) => void,
|
|
165
|
+
): Promise<Subscription>
|
|
166
|
+
|
|
167
|
+
Subscribe to an event.
|
|
168
|
+
The `event` has to be a valid MQTT topic name.
|
|
169
|
+
The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
170
|
+
The `callback` is called with the `params` passed to a remote `emit()`.
|
|
171
|
+
There is no return value of `callback`.
|
|
172
|
+
|
|
173
|
+
Internally, on the MQTT broker, the topics generated by
|
|
174
|
+
`topicEventNoticeMake()` (default: `${event}/event-notice` and
|
|
175
|
+
`${event}/event-notice/${clientId}`) are subscribed. Returns a
|
|
176
|
+
`Subscription` object with an `unsubscribe()` method.
|
|
177
|
+
|
|
178
|
+
- **Service Registration**:<br/>
|
|
179
|
+
|
|
180
|
+
/* (simplified TypeScript API method signature) */
|
|
181
|
+
register(
|
|
182
|
+
service: string,
|
|
183
|
+
options?: MQTT::IClientSubscribeOptions
|
|
184
|
+
callback: (...params: any[]) => any,
|
|
185
|
+
): Promise<Registration>
|
|
186
|
+
|
|
187
|
+
Register a service.
|
|
188
|
+
The `service` has to be a valid MQTT topic name.
|
|
189
|
+
The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
190
|
+
The `callback` is called with the `params` passed to a remote `call()`.
|
|
191
|
+
The return value of `callback` will resolve the `Promise` returned by the remote `call()`.
|
|
192
|
+
|
|
193
|
+
Internally, on the MQTT broker, the topics by
|
|
194
|
+
`topicServiceRequestMake()` (default: `${service}/service-request` and
|
|
195
|
+
`${service}/service-request/${clientId}`) are subscribed. Returns a
|
|
196
|
+
`Registration` object with an `unregister()` method.
|
|
197
|
+
|
|
198
|
+
- **Event Emission**:<br/>
|
|
199
|
+
|
|
200
|
+
/* (simplified TypeScript API method signature) */
|
|
201
|
+
emit(
|
|
202
|
+
event: string,
|
|
203
|
+
clientId?: ClientId,
|
|
204
|
+
options?: MQTT::IClientSubscribeOptions,
|
|
205
|
+
...params: any[]
|
|
206
|
+
): void
|
|
207
|
+
|
|
208
|
+
Emit an event to all subscribers or a specific subscriber ("fire and forget").
|
|
209
|
+
The optional `clientId` directs the event to a specific subscriber only.
|
|
210
|
+
The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
211
|
+
|
|
212
|
+
The remote `subscribe()` `callback` is called with `params` and its
|
|
213
|
+
return value is silently ignored.
|
|
214
|
+
|
|
215
|
+
Internally, publishes to the MQTT topic by `topicEventNoticeMake(event, clientId)`
|
|
216
|
+
(default: `${event}/event-notice` or `${event}/event-notice/${clientId}`).
|
|
217
|
+
|
|
218
|
+
- **Service Call**:<br/>
|
|
219
|
+
|
|
220
|
+
/* (simplified TypeScript API method signature) */
|
|
221
|
+
call(
|
|
222
|
+
service: string,
|
|
223
|
+
clientId?: ClientId,
|
|
224
|
+
options?: MQTT::IClientSubscribeOptions,
|
|
225
|
+
...params: any[]
|
|
226
|
+
): Promise<any>
|
|
227
|
+
|
|
228
|
+
Call a service on all registrants or on a specific registrant ("request and response").
|
|
229
|
+
The optional `clientId` directs the call to a specific registrant only.
|
|
230
|
+
The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
231
|
+
|
|
232
|
+
The remote `register()` `callback` is called with `params` and its
|
|
233
|
+
return value resolves the returned `Promise`. If the remote `callback`
|
|
234
|
+
throws an exception, this rejects the returned `Promise`.
|
|
235
|
+
|
|
236
|
+
Internally, on the MQTT broker, the topic by `topicServiceResponseMake(service, clientId)`
|
|
237
|
+
(default: `${service}/service-response/${clientId}`) is temporarily subscribed
|
|
238
|
+
for receiving the response.
|
|
239
|
+
|
|
240
|
+
- **Client Id Wrapping**:<br/>
|
|
241
|
+
|
|
242
|
+
clientId(
|
|
243
|
+
id: string
|
|
244
|
+
): ClientId
|
|
245
|
+
|
|
246
|
+
Wrap a client ID string for use with `emit()` or `call()` to direct the
|
|
247
|
+
message to a specific client. Returns a `ClientId` object.
|
|
110
248
|
|
|
111
249
|
Internals
|
|
112
250
|
---------
|
|
113
251
|
|
|
114
|
-
|
|
115
|
-
|
|
252
|
+
In the following, assume that an RPC instance is created with:
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
import MQTT from "mqtt"
|
|
256
|
+
import RPC from "mqtt-json-rpc"
|
|
257
|
+
|
|
258
|
+
const mqtt = MQTT.connect("...", { ... })
|
|
259
|
+
const rpc = new RPC(mqtt, { clientId: "d1acc980-0e4e-11e8-98f0-ab5030b47df4", codec: "json" })
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Internally, remote services are assigned to MQTT topics. When calling a
|
|
263
|
+
remote service named `example/hello` with parameters `"world"` and `42` via...
|
|
116
264
|
|
|
117
|
-
```
|
|
265
|
+
```ts
|
|
118
266
|
rpc.call("example/hello", "world", 42).then((result) => {
|
|
119
267
|
...
|
|
120
268
|
})
|
|
121
269
|
```
|
|
122
270
|
|
|
123
271
|
...the following JSON-RPC 2.0 request message is sent to the permanent MQTT
|
|
124
|
-
topic `example/hello/request
|
|
272
|
+
topic `example/hello/service-request` (UUID `d1db7aa0-0e4e-11e8-b1d9-5f0ab230c0d9` is
|
|
273
|
+
a random generated one):
|
|
125
274
|
|
|
126
275
|
```json
|
|
127
276
|
{
|
|
@@ -132,18 +281,18 @@ topic `example/hello/request`:
|
|
|
132
281
|
}
|
|
133
282
|
```
|
|
134
283
|
|
|
135
|
-
Beforehand, this `example/hello`
|
|
284
|
+
Beforehand, this `example/hello` service should have been registered with...
|
|
136
285
|
|
|
137
|
-
```
|
|
286
|
+
```ts
|
|
138
287
|
rpc.register("example/hello", (a1, a2) => {
|
|
139
288
|
return `${a1}:${a2}`
|
|
140
289
|
})
|
|
141
290
|
```
|
|
142
291
|
|
|
143
|
-
...and then its result, in the above `rpc.call` example `"world:42"`, is then
|
|
292
|
+
...and then its result, in the above `rpc.call()` example `"world:42"`, is then
|
|
144
293
|
sent back as the following JSON-RPC 2.0 success response
|
|
145
294
|
message to the temporary (client-specific) MQTT topic
|
|
146
|
-
`example/hello/response/d1acc980-0e4e-11e8-98f0-ab5030b47df4`:
|
|
295
|
+
`example/hello/service-response/d1acc980-0e4e-11e8-98f0-ab5030b47df4`:
|
|
147
296
|
|
|
148
297
|
```json
|
|
149
298
|
{
|
|
@@ -153,18 +302,18 @@ message to the temporary (client-specific) MQTT topic
|
|
|
153
302
|
}
|
|
154
303
|
```
|
|
155
304
|
|
|
156
|
-
The JSON-RPC 2.0 `id` field always consists of
|
|
157
|
-
|
|
158
|
-
the UUID v1 of the particular
|
|
305
|
+
The JSON-RPC 2.0 `id` field always consists of `clientId:requestId`, where
|
|
306
|
+
`clientId` is the UUID v1 of the RPC client instance and `requestId` is
|
|
307
|
+
the UUID v1 of the particular service request. The `clientId` is used for
|
|
159
308
|
sending back the JSON-RPC 2.0 response message to the requestor only.
|
|
160
|
-
The
|
|
309
|
+
The `requestId` is used for correlating the response to the request only.
|
|
161
310
|
|
|
162
|
-
|
|
163
|
-
|
|
311
|
+
Broker Setup
|
|
312
|
+
------------
|
|
164
313
|
|
|
165
314
|
For a real test-drive of MQTT-JSON-RPC, install the
|
|
166
|
-
[Mosquitto](https://mosquitto.org/) MQTT broker
|
|
167
|
-
|
|
315
|
+
[Mosquitto](https://mosquitto.org/) MQTT broker and a `mosquitto.conf`
|
|
316
|
+
file like...
|
|
168
317
|
|
|
169
318
|
```
|
|
170
319
|
[...]
|
|
@@ -174,14 +323,10 @@ acl_file mosquitto-acl.txt
|
|
|
174
323
|
|
|
175
324
|
[...]
|
|
176
325
|
|
|
177
|
-
# additional listener
|
|
178
|
-
listener
|
|
326
|
+
# additional listener
|
|
327
|
+
listener 1883 127.0.0.1
|
|
179
328
|
max_connections -1
|
|
180
|
-
protocol
|
|
181
|
-
cafile mosquitto-ca.crt.pem
|
|
182
|
-
certfile mosquitto-sv.crt.pem
|
|
183
|
-
keyfile mosquitto-sv.key.pem
|
|
184
|
-
require_certificate false
|
|
329
|
+
protocol mqtt
|
|
185
330
|
|
|
186
331
|
[...]
|
|
187
332
|
```
|
|
@@ -199,20 +344,38 @@ topic readwrite example/#
|
|
|
199
344
|
example:$6$awYNe6oCAi+xlvo5$mWIUqyy4I0O3nJ99lP1mkRVqsDGymF8en5NChQQxf7KrVJLUp1SzrrVDe94wWWJa3JGIbOXD9wfFGZdi948e6A==
|
|
200
345
|
```
|
|
201
346
|
|
|
202
|
-
|
|
203
|
-
|
|
347
|
+
Alternatively, you can use the [NPM package mosquitto](https://npmjs.com/mosquitto)
|
|
348
|
+
for an equal setup.
|
|
204
349
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const RPC = require("mqtt-json-rpc")
|
|
350
|
+
Example
|
|
351
|
+
-------
|
|
208
352
|
|
|
209
|
-
|
|
210
|
-
|
|
353
|
+
You can test-drive MQTT-JSON-RPC with a complete [sample](sample/sample.ts) to see
|
|
354
|
+
MQTT-JSON-RPC in action and tracing its communication (the typing of the `RPC`
|
|
355
|
+
class with `API` is optional, but strongly suggested):
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
import Mosquitto from "mosquitto"
|
|
359
|
+
import MQTT from "mqtt"
|
|
360
|
+
import RPC from "mqtt-json-rpc"
|
|
361
|
+
|
|
362
|
+
const mosquitto = new Mosquitto()
|
|
363
|
+
await mosquitto.start()
|
|
364
|
+
await new Promise((resolve) => { setTimeout(resolve, 500) })
|
|
365
|
+
|
|
366
|
+
const mqtt = MQTT.connect("mqtt://127.0.0.1:1883", {
|
|
211
367
|
username: "example",
|
|
212
368
|
password: "example"
|
|
213
369
|
})
|
|
214
370
|
|
|
215
|
-
|
|
371
|
+
type API = {
|
|
372
|
+
"example/sample": (a1: string, a2: number) => void
|
|
373
|
+
"example/hello": (a1: string, a2: number) => string
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const rpc = new RPC<API>(mqtt, { codec: "json" })
|
|
377
|
+
|
|
378
|
+
type Sample = (a: string, b: number) => string
|
|
216
379
|
|
|
217
380
|
mqtt.on("error", (err) => { console.log("ERROR", err) })
|
|
218
381
|
mqtt.on("offline", () => { console.log("OFFLINE") })
|
|
@@ -227,8 +390,9 @@ mqtt.on("connect", () => {
|
|
|
227
390
|
return `${a1}:${a2}`
|
|
228
391
|
})
|
|
229
392
|
rpc.call("example/hello", "world", 42).then((result) => {
|
|
230
|
-
console.log("example/hello
|
|
393
|
+
console.log("example/hello success: ", result)
|
|
231
394
|
mqtt.end()
|
|
395
|
+
await mosquitto.stop()
|
|
232
396
|
}).catch((err) => {
|
|
233
397
|
console.log("example/hello error: ", err)
|
|
234
398
|
})
|
|
@@ -238,12 +402,12 @@ mqtt.on("connect", () => {
|
|
|
238
402
|
The output will be:
|
|
239
403
|
|
|
240
404
|
```
|
|
241
|
-
$ node sample.
|
|
405
|
+
$ node sample.ts
|
|
242
406
|
CONNECT
|
|
243
|
-
RECEIVED example/hello/request {"jsonrpc":"2.0","id":"
|
|
407
|
+
RECEIVED example/hello/service-request {"jsonrpc":"2.0","id":"b441fe30-e8af-11f0-b361-a30e779baa27:b474f510-e8af-11f0-ace2-97e30fcf7dca","method":"example/hello","params":["world",42]}
|
|
244
408
|
example/hello: request: world 42
|
|
245
|
-
RECEIVED example/hello/response/
|
|
246
|
-
example/hello
|
|
409
|
+
RECEIVED example/hello/service-response/b441fe30-e8af-11f0-b361-a30e779baa27 {"jsonrpc":"2.0","id":"b441fe30-e8af-11f0-b361-a30e779baa27:b474f510-e8af-11f0-ace2-97e30fcf7dca","result":"world:42"}
|
|
410
|
+
example/hello success: world:42
|
|
247
411
|
CLOSE
|
|
248
412
|
```
|
|
249
413
|
|