mqtt-json-rpc 2.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +249 -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 +5 -3
- 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,8 @@ 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)
|
|
12
14
|
|
|
13
15
|
Installation
|
|
14
16
|
------------
|
|
@@ -20,44 +22,81 @@ $ npm install mqtt mqtt-json-rpc
|
|
|
20
22
|
About
|
|
21
23
|
-----
|
|
22
24
|
|
|
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)
|
|
25
|
+
This is an addon API for the excellent
|
|
26
|
+
[MQTT.js](https://www.npmjs.com/package/mqtt) JavaScript/TypeScript API
|
|
27
|
+
for [Remote Procedure Call](https://en.wikipedia.org/wiki/Remote_procedure_call) (RPC)
|
|
27
28
|
communication based on the [JSON-RPC](http://www.jsonrpc.org/)
|
|
28
29
|
protocol. This allows a bi-directional request/response-style communication over
|
|
29
30
|
the technically uni-directional message protocol [MQTT](http://mqtt.org).
|
|
30
31
|
|
|
32
|
+
Conceptually, this RPC API provides two types of communication patterns:
|
|
33
|
+
|
|
34
|
+
- **Event Emission**:
|
|
35
|
+
Event Emission is a *uni-directional* communication pattern.
|
|
36
|
+
An Event is the combination of an event name and optionally zero or more arguments.
|
|
37
|
+
You *subscribe* to events.
|
|
38
|
+
When an event is *emitted*, either a single particular subscriber (in case of
|
|
39
|
+
a directed event emission) or all subscribers are called and receive the
|
|
40
|
+
arguments as extra information.
|
|
41
|
+
|
|
42
|
+
- **Service Call**:
|
|
43
|
+
Service Call is a *bi-directional* communication pattern.
|
|
44
|
+
A Service is the combination of a service name and optionally zero or more arguments.
|
|
45
|
+
You *register* for a service.
|
|
46
|
+
When a service is *called*, a single particular registrator (in case
|
|
47
|
+
of a directed service call) or one arbitrary registrator is called and
|
|
48
|
+
receives the arguments as the request. The registrator then has to
|
|
49
|
+
provide the service response.
|
|
50
|
+
|
|
51
|
+
Notice: while the provided Event Emission functionality is just a very thing
|
|
52
|
+
wrapper around the regular MQTT message publishing API of MQTT.js, the
|
|
53
|
+
Service Call functionality is the core and heart of this addon API.
|
|
54
|
+
|
|
31
55
|
Usage
|
|
32
56
|
-----
|
|
33
57
|
|
|
34
|
-
|
|
58
|
+
### API:
|
|
35
59
|
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
60
|
+
```ts
|
|
61
|
+
export type API = {
|
|
62
|
+
"example/sample": (a1: string, a2: boolean) => void
|
|
63
|
+
"example/hello": (a1: string, a2: number) => string
|
|
64
|
+
}
|
|
65
|
+
```
|
|
39
66
|
|
|
40
|
-
|
|
41
|
-
const rpc = new RPC(mqtt)
|
|
67
|
+
### Server:
|
|
42
68
|
|
|
43
|
-
|
|
69
|
+
```ts
|
|
70
|
+
import MQTT from "mqtt"
|
|
71
|
+
import RPC from "mqtt-json-rpc"
|
|
72
|
+
import type { API } from [...]
|
|
73
|
+
|
|
74
|
+
const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
75
|
+
const rpc = new RPC<API>(mqtt)
|
|
76
|
+
|
|
77
|
+
mqtt.on("connect", async () => {
|
|
78
|
+
rpc.subscribe("example/sample", (a1, a2) => {
|
|
79
|
+
console.log("example/sample: ", a1, a2)
|
|
80
|
+
})
|
|
44
81
|
rpc.register("example/hello", (a1, a2) => {
|
|
45
|
-
console.log("example/hello:
|
|
82
|
+
console.log("example/hello: ", a1, a2)
|
|
46
83
|
return `${a1}:${a2}`
|
|
47
84
|
})
|
|
48
85
|
})
|
|
49
86
|
```
|
|
50
87
|
|
|
51
|
-
|
|
88
|
+
### Client:
|
|
52
89
|
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
|
|
90
|
+
```ts
|
|
91
|
+
import MQTT from "mqtt"
|
|
92
|
+
import RPC from "mqtt-json-rpc"
|
|
93
|
+
import type { API } from [...]
|
|
56
94
|
|
|
57
|
-
const mqtt = MQTT.connect("wss://127.0.0.1:
|
|
58
|
-
const rpc = new RPC(mqtt)
|
|
95
|
+
const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
96
|
+
const rpc = new RPC<API>(mqtt)
|
|
59
97
|
|
|
60
98
|
mqtt.on("connect", () => {
|
|
99
|
+
rpc.emit("example/sample", "foo", true)
|
|
61
100
|
rpc.call("example/hello", "world", 42).then((response) => {
|
|
62
101
|
console.log("example/hello response: ", response)
|
|
63
102
|
mqtt.end()
|
|
@@ -68,60 +107,160 @@ mqtt.on("connect", () => {
|
|
|
68
107
|
Application Programming Interface
|
|
69
108
|
---------------------------------
|
|
70
109
|
|
|
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
|
-
|
|
110
|
+
The RPC API provides the following methods:
|
|
111
|
+
|
|
112
|
+
- **Construction**:<br/>
|
|
113
|
+
|
|
114
|
+
constructor(
|
|
115
|
+
mqtt: MqttClient,
|
|
116
|
+
options?: {
|
|
117
|
+
clientId: string
|
|
118
|
+
codec: "cbor" | "json"
|
|
119
|
+
timeout: number
|
|
120
|
+
topicEventNoticeMake: (topic: string) => TopicMatching | null
|
|
121
|
+
topicServiceRequestMake: (topic: string) => TopicMatching | null
|
|
122
|
+
topicServiceResponseMake: (topic: string) => TopicMatching | null
|
|
123
|
+
topicEventNoticeMatch: { name: string, clientId?: string }
|
|
124
|
+
topicServiceRequestMatch: { name: string, clientId?: string }
|
|
125
|
+
topicServiceResponseMatch: { name: string, clientId?: string }
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
The `mqtt` is the [MQTT.js](https://www.npmjs.com/package/mqtt) instance,
|
|
130
|
+
which has to be establish separately.
|
|
131
|
+
The optional `options` object supports the following fields:
|
|
132
|
+
- `clientId`: Custom client identifier (default: auto-generated UUID v1).
|
|
133
|
+
- `codec`: Encoding format (default: `cbor`).
|
|
134
|
+
- `timeout`: Communication timeout in milliseconds (default: `10000`).
|
|
135
|
+
- `topicEventNoticeMake`: Custom topic generation for event notices.
|
|
136
|
+
(default: `` (name, clientId) => clientId ? `${name}/event-notice/${clientId}` : `${name}/event-notice` ``)
|
|
137
|
+
- `topicServiceRequestMake`: Custom topic generation for service requests.
|
|
138
|
+
(default: `` (name, clientId) => clientId ? `${name}/service-request/${clientId}` : `${name}/service-request` ``)
|
|
139
|
+
- `topicServiceResponseMake`): Custom topic generation for service responses.
|
|
140
|
+
(default: `` (name, clientId) => clientId ? `${name}/service-response/${clientId}` : `${name}/service-response` ``)
|
|
141
|
+
- `topicEventNoticeMatch`: Custom topic matching for event notices.
|
|
142
|
+
(default: `` (topic) => { const m = topic.match(/^(.+?)\/event-notice(?:\/(.+))?$/); return m ? { name: m[1], clientId: m[2] } : null } ``)
|
|
143
|
+
- `topicServiceRequestMatch`: Custom topic matching for service requests.
|
|
144
|
+
(default: `` (topic) => { const m = topic.match(/^(.+?)\/service-request(?:\/(.+))?$/); return m ? { name: m[1], clientId: m[2] } : null } ``)
|
|
145
|
+
- `topicServiceResponseMatch`: Custom topic matching for service responses.
|
|
146
|
+
(default: `` (topic) => { const m = topic.match(/^(.+?)\/service-response\/(.+)$/); return m ? { name: m[1], clientId: m[2] } : null } ``)
|
|
147
|
+
|
|
148
|
+
- **Event Subscription**:<br/>
|
|
149
|
+
|
|
150
|
+
/* (simplified TypeScript API method signature) */
|
|
151
|
+
subscribe(
|
|
152
|
+
event: string,
|
|
153
|
+
options?: MQTT::IClientSubscribeOptions
|
|
154
|
+
callback: (...params: any[]) => void,
|
|
155
|
+
): Promise<Subscription>
|
|
156
|
+
|
|
157
|
+
Subscribe to an event.
|
|
158
|
+
The `event` has to be a valid MQTT topic name.
|
|
159
|
+
The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
160
|
+
The `callback` is called with the `params` passed to a remote `emit()`.
|
|
161
|
+
There is no return value of `callback`.
|
|
162
|
+
|
|
163
|
+
Internally, on the MQTT broker, the topics generated by
|
|
164
|
+
`topicEventNoticeMake()` (default: `${event}/event-notice` and
|
|
165
|
+
`${event}/event-notice/${clientId}`) are subscribed. Returns a
|
|
166
|
+
`Subscription` object with an `unsubscribe()` method.
|
|
167
|
+
|
|
168
|
+
- **Service Registration**:<br/>
|
|
169
|
+
|
|
170
|
+
/* (simplified TypeScript API method signature) */
|
|
171
|
+
register(
|
|
172
|
+
service: string,
|
|
173
|
+
options?: MQTT::IClientSubscribeOptions
|
|
174
|
+
callback: (...params: any[]) => any,
|
|
175
|
+
): Promise<Registration>
|
|
176
|
+
|
|
177
|
+
Register a service.
|
|
178
|
+
The `service` has to be a valid MQTT topic name.
|
|
179
|
+
The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
180
|
+
The `callback` is called with the `params` passed to a remote `call()`.
|
|
181
|
+
The return value of `callback` will resolve the `Promise` returned by the remote `call()`.
|
|
182
|
+
|
|
183
|
+
Internally, on the MQTT broker, the topics by
|
|
184
|
+
`topicServiceRequestMake()` (default: `${service}/service-request` and
|
|
185
|
+
`${service}/service-request/${clientId}`) are subscribed. Returns a
|
|
186
|
+
`Registration` object with an `unregister()` method.
|
|
187
|
+
|
|
188
|
+
- **Event Emission**:<br/>
|
|
189
|
+
|
|
190
|
+
/* (simplified TypeScript API method signature) */
|
|
191
|
+
emit(
|
|
192
|
+
event: string,
|
|
193
|
+
clientId?: ClientId,
|
|
194
|
+
options?: MQTT::IClientSubscribeOptions,
|
|
195
|
+
...params: any[]
|
|
196
|
+
): void
|
|
197
|
+
|
|
198
|
+
Emit an event to all subscribers or a specific subscriber ("fire and forget").
|
|
199
|
+
The optional `clientId` directs the event to a specific subscriber only.
|
|
200
|
+
The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
201
|
+
|
|
202
|
+
The remote `subscribe()` `callback` is called with `params` and its
|
|
203
|
+
return value is silently ignored.
|
|
204
|
+
|
|
205
|
+
Internally, publishes to the MQTT topic by `topicEventNoticeMake(event, clientId)`
|
|
206
|
+
(default: `${event}/event-notice` or `${event}/event-notice/${clientId}`).
|
|
207
|
+
|
|
208
|
+
- **Service Call**:<br/>
|
|
209
|
+
|
|
210
|
+
/* (simplified TypeScript API method signature) */
|
|
211
|
+
call(
|
|
212
|
+
service: string,
|
|
213
|
+
clientId?: ClientId,
|
|
214
|
+
options?: MQTT::IClientSubscribeOptions,
|
|
215
|
+
...params: any[]
|
|
216
|
+
): Promise<any>
|
|
217
|
+
|
|
218
|
+
Call a service on all registrants or on a specific registrant ("request and response").
|
|
219
|
+
The optional `clientId` directs the call to a specific registrant only.
|
|
220
|
+
The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
221
|
+
|
|
222
|
+
The remote `register()` `callback` is called with `params` and its
|
|
223
|
+
return value resolves the returned `Promise`. If the remote `callback`
|
|
224
|
+
throws an exception, this rejects the returned `Promise`.
|
|
225
|
+
|
|
226
|
+
Internally, on the MQTT broker, the topic by `topicServiceResponseMake(service, clientId)`
|
|
227
|
+
(default: `${service}/service-response/${clientId}`) is temporarily subscribed
|
|
228
|
+
for receiving the response.
|
|
229
|
+
|
|
230
|
+
- **Client Id Wrapping**:<br/>
|
|
231
|
+
|
|
232
|
+
clientId(
|
|
233
|
+
id: string
|
|
234
|
+
): ClientId
|
|
235
|
+
|
|
236
|
+
Wrap a client ID string for use with `emit()` or `call()` to direct the
|
|
237
|
+
message to a specific client. Returns a `ClientId` object.
|
|
110
238
|
|
|
111
239
|
Internals
|
|
112
240
|
---------
|
|
113
241
|
|
|
114
|
-
|
|
115
|
-
|
|
242
|
+
In the following, assume that an RPC instance is created with:
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
import MQTT from "mqtt"
|
|
246
|
+
import RPC from "mqtt-json-rpc"
|
|
247
|
+
|
|
248
|
+
const mqtt = MQTT.connect("...", { ... })
|
|
249
|
+
const rpc = new RPC(mqtt, { clientId: "d1acc980-0e4e-11e8-98f0-ab5030b47df4", codec: "json" })
|
|
250
|
+
```
|
|
116
251
|
|
|
117
|
-
|
|
252
|
+
Internally, remote services are assigned to MQTT topics. When calling a
|
|
253
|
+
remote service named `example/hello` with parameters `"world"` and `42` via...
|
|
254
|
+
|
|
255
|
+
```ts
|
|
118
256
|
rpc.call("example/hello", "world", 42).then((result) => {
|
|
119
257
|
...
|
|
120
258
|
})
|
|
121
259
|
```
|
|
122
260
|
|
|
123
261
|
...the following JSON-RPC 2.0 request message is sent to the permanent MQTT
|
|
124
|
-
topic `example/hello/request
|
|
262
|
+
topic `example/hello/service-request` (UUID `d1db7aa0-0e4e-11e8-b1d9-5f0ab230c0d9` is
|
|
263
|
+
a random generated one):
|
|
125
264
|
|
|
126
265
|
```json
|
|
127
266
|
{
|
|
@@ -132,18 +271,18 @@ topic `example/hello/request`:
|
|
|
132
271
|
}
|
|
133
272
|
```
|
|
134
273
|
|
|
135
|
-
Beforehand, this `example/hello`
|
|
274
|
+
Beforehand, this `example/hello` service should have been registered with...
|
|
136
275
|
|
|
137
|
-
```
|
|
276
|
+
```ts
|
|
138
277
|
rpc.register("example/hello", (a1, a2) => {
|
|
139
278
|
return `${a1}:${a2}`
|
|
140
279
|
})
|
|
141
280
|
```
|
|
142
281
|
|
|
143
|
-
...and then its result, in the above `rpc.call` example `"world:42"`, is then
|
|
282
|
+
...and then its result, in the above `rpc.call()` example `"world:42"`, is then
|
|
144
283
|
sent back as the following JSON-RPC 2.0 success response
|
|
145
284
|
message to the temporary (client-specific) MQTT topic
|
|
146
|
-
`example/hello/response/d1acc980-0e4e-11e8-98f0-ab5030b47df4`:
|
|
285
|
+
`example/hello/service-response/d1acc980-0e4e-11e8-98f0-ab5030b47df4`:
|
|
147
286
|
|
|
148
287
|
```json
|
|
149
288
|
{
|
|
@@ -153,18 +292,18 @@ message to the temporary (client-specific) MQTT topic
|
|
|
153
292
|
}
|
|
154
293
|
```
|
|
155
294
|
|
|
156
|
-
The JSON-RPC 2.0 `id` field always consists of
|
|
157
|
-
|
|
158
|
-
the UUID v1 of the particular
|
|
295
|
+
The JSON-RPC 2.0 `id` field always consists of `clientId:requestId`, where
|
|
296
|
+
`clientId` is the UUID v1 of the RPC client instance and `requestId` is
|
|
297
|
+
the UUID v1 of the particular service request. The `clientId` is used for
|
|
159
298
|
sending back the JSON-RPC 2.0 response message to the requestor only.
|
|
160
|
-
The
|
|
299
|
+
The `requestId` is used for correlating the response to the request only.
|
|
161
300
|
|
|
162
|
-
|
|
163
|
-
|
|
301
|
+
Broker Setup
|
|
302
|
+
------------
|
|
164
303
|
|
|
165
304
|
For a real test-drive of MQTT-JSON-RPC, install the
|
|
166
|
-
[Mosquitto](https://mosquitto.org/) MQTT broker
|
|
167
|
-
|
|
305
|
+
[Mosquitto](https://mosquitto.org/) MQTT broker and a `mosquitto.conf`
|
|
306
|
+
file like...
|
|
168
307
|
|
|
169
308
|
```
|
|
170
309
|
[...]
|
|
@@ -174,14 +313,10 @@ acl_file mosquitto-acl.txt
|
|
|
174
313
|
|
|
175
314
|
[...]
|
|
176
315
|
|
|
177
|
-
# additional listener
|
|
178
|
-
listener
|
|
316
|
+
# additional listener
|
|
317
|
+
listener 1883 127.0.0.1
|
|
179
318
|
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
|
|
319
|
+
protocol mqtt
|
|
185
320
|
|
|
186
321
|
[...]
|
|
187
322
|
```
|
|
@@ -199,20 +334,38 @@ topic readwrite example/#
|
|
|
199
334
|
example:$6$awYNe6oCAi+xlvo5$mWIUqyy4I0O3nJ99lP1mkRVqsDGymF8en5NChQQxf7KrVJLUp1SzrrVDe94wWWJa3JGIbOXD9wfFGZdi948e6A==
|
|
200
335
|
```
|
|
201
336
|
|
|
202
|
-
|
|
203
|
-
|
|
337
|
+
Alternatively, you can use the [NPM package mosquitto](https://npmjs.com/mosquitto)
|
|
338
|
+
for an equal setup.
|
|
339
|
+
|
|
340
|
+
Example
|
|
341
|
+
-------
|
|
342
|
+
|
|
343
|
+
You can test-drive MQTT-JSON-RPC with a complete [sample](sample/sample.ts) to see
|
|
344
|
+
MQTT-JSON-RPC in action and tracing its communication (the typing of the `RPC`
|
|
345
|
+
class with `API` is optional, but strongly suggested):
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
import Mosquitto from "mosquitto"
|
|
349
|
+
import MQTT from "mqtt"
|
|
350
|
+
import RPC from "mqtt-json-rpc"
|
|
204
351
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
352
|
+
const mosquitto = new Mosquitto()
|
|
353
|
+
await mosquitto.start()
|
|
354
|
+
await new Promise((resolve) => { setTimeout(resolve, 500) })
|
|
208
355
|
|
|
209
|
-
const mqtt = MQTT.connect("
|
|
210
|
-
rejectUnauthorized: false,
|
|
356
|
+
const mqtt = MQTT.connect("mqtt://127.0.0.1:1883", {
|
|
211
357
|
username: "example",
|
|
212
358
|
password: "example"
|
|
213
359
|
})
|
|
214
360
|
|
|
215
|
-
|
|
361
|
+
type API = {
|
|
362
|
+
"example/sample": (a1: string, a2: number) => void
|
|
363
|
+
"example/hello": (a1: string, a2: number) => string
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const rpc = new RPC<API>(mqtt, { codec: "json" })
|
|
367
|
+
|
|
368
|
+
type Sample = (a: string, b: number) => string
|
|
216
369
|
|
|
217
370
|
mqtt.on("error", (err) => { console.log("ERROR", err) })
|
|
218
371
|
mqtt.on("offline", () => { console.log("OFFLINE") })
|
|
@@ -227,8 +380,9 @@ mqtt.on("connect", () => {
|
|
|
227
380
|
return `${a1}:${a2}`
|
|
228
381
|
})
|
|
229
382
|
rpc.call("example/hello", "world", 42).then((result) => {
|
|
230
|
-
console.log("example/hello
|
|
383
|
+
console.log("example/hello success: ", result)
|
|
231
384
|
mqtt.end()
|
|
385
|
+
await mosquitto.stop()
|
|
232
386
|
}).catch((err) => {
|
|
233
387
|
console.log("example/hello error: ", err)
|
|
234
388
|
})
|
|
@@ -238,12 +392,12 @@ mqtt.on("connect", () => {
|
|
|
238
392
|
The output will be:
|
|
239
393
|
|
|
240
394
|
```
|
|
241
|
-
$ node sample.
|
|
395
|
+
$ node sample.ts
|
|
242
396
|
CONNECT
|
|
243
|
-
RECEIVED example/hello/request {"jsonrpc":"2.0","id":"
|
|
397
|
+
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
398
|
example/hello: request: world 42
|
|
245
|
-
RECEIVED example/hello/response/
|
|
246
|
-
example/hello
|
|
399
|
+
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"}
|
|
400
|
+
example/hello success: world:42
|
|
247
401
|
CLOSE
|
|
248
402
|
```
|
|
249
403
|
|