@seriousme/opifex 1.6.2 → 1.7.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.
Files changed (128) hide show
  1. package/README.md +6 -7
  2. package/bin/conformanceServer.ts +67 -16
  3. package/bin/demoServer.ts +69 -14
  4. package/bin/mqtt.ts +30 -0
  5. package/client/ConnectionState.ts +12 -0
  6. package/client/client.ts +56 -2
  7. package/client/context.ts +5 -0
  8. package/client/handlers/handleConnack.ts +6 -0
  9. package/client/handlers/handlePacket.ts +7 -0
  10. package/client/handlers/handlePuback.ts +8 -2
  11. package/client/handlers/handlePubcomp.ts +10 -4
  12. package/client/handlers/handlePublish.ts +6 -2
  13. package/client/handlers/handlePubrec.ts +13 -6
  14. package/client/handlers/handlePubrel.ts +16 -6
  15. package/client/handlers/handleSuback.ts +9 -6
  16. package/client/handlers/handleUnsuback.ts +10 -3
  17. package/client/store/memoryStore.ts +25 -0
  18. package/client/store/store.ts +39 -0
  19. package/deno/tcpServer.test.ts +137 -2
  20. package/node/tcpServer.test.ts +61 -6
  21. package/node/tcpServer.ts +9 -2
  22. package/node/wrapNodeSocket.ts +13 -2
  23. package/package.json +13 -3
  24. package/persistence/memory/memoryPersistence.test.ts +2 -1
  25. package/persistence/memory/memoryPersistence.ts +1 -0
  26. package/persistence/store.ts +1 -0
  27. package/server/handlers/handleConnect.ts +49 -6
  28. package/server/handlers/handleDisconnect.ts +5 -0
  29. package/server/handlers/handlePacket.ts +7 -0
  30. package/server/handlers/handlePingreq.ts +6 -0
  31. package/server/handlers/handlePuback.ts +9 -2
  32. package/server/handlers/handlePubcomp.ts +8 -3
  33. package/server/handlers/handlePublish.ts +13 -0
  34. package/server/handlers/handlePubrec.ts +11 -3
  35. package/server/handlers/handlePubrel.ts +12 -4
  36. package/server/handlers/handleSubscribe.ts +28 -5
  37. package/server/handlers/handleUnsubscribe.ts +6 -0
  38. package/utils/asyncQueue.ts +2 -1
  39. package/utils/nextTick.ts +13 -1
  40. package/.github/workflows/closeStale.yml +0 -15
  41. package/.github/workflows/codeql-analysis.yml +0 -71
  42. package/.github/workflows/deno-ci.yml +0 -16
  43. package/.github/workflows/nodejs-ci.yml +0 -23
  44. package/.github/workflows/publish.yml +0 -16
  45. package/.github/workflows/update-license-year.sh +0 -14
  46. package/.github/workflows/update-license-year.yml +0 -13
  47. package/CHANGELOG.md +0 -74
  48. package/deno.json +0 -15
  49. package/deno.lock +0 -34
  50. package/dist/bin/conformanceServer.js +0 -51
  51. package/dist/bin/demoServer.js +0 -46
  52. package/dist/bin/mqtt.js +0 -227
  53. package/dist/client/ConnectionState.js +0 -7
  54. package/dist/client/client.js +0 -132
  55. package/dist/client/context.js +0 -148
  56. package/dist/client/deps.js +0 -5
  57. package/dist/client/handlers/handleConnack.js +0 -18
  58. package/dist/client/handlers/handlePacket.js +0 -50
  59. package/dist/client/handlers/handlePuback.js +0 -6
  60. package/dist/client/handlers/handlePubcomp.js +0 -9
  61. package/dist/client/handlers/handlePublish.js +0 -28
  62. package/dist/client/handlers/handlePubrec.js +0 -17
  63. package/dist/client/handlers/handlePubrel.js +0 -19
  64. package/dist/client/handlers/handleSuback.js +0 -9
  65. package/dist/client/handlers/handleUnsuback.js +0 -7
  66. package/dist/client/mod.js +0 -5
  67. package/dist/client/store/deps.js +0 -1
  68. package/dist/client/store/memoryStore.js +0 -36
  69. package/dist/client/store/store.js +0 -1
  70. package/dist/mqttConn/mqttConn.js +0 -104
  71. package/dist/mqttPacket/AuthenticationResult.js +0 -16
  72. package/dist/mqttPacket/BitMask.js +0 -10
  73. package/dist/mqttPacket/PacketType.js +0 -18
  74. package/dist/mqttPacket/connack.js +0 -27
  75. package/dist/mqttPacket/connect.js +0 -115
  76. package/dist/mqttPacket/decoder.js +0 -89
  77. package/dist/mqttPacket/disconnect.js +0 -14
  78. package/dist/mqttPacket/encoder.js +0 -56
  79. package/dist/mqttPacket/length.js +0 -43
  80. package/dist/mqttPacket/mod.js +0 -76
  81. package/dist/mqttPacket/pingreq.js +0 -15
  82. package/dist/mqttPacket/pingres.js +0 -14
  83. package/dist/mqttPacket/puback.js +0 -20
  84. package/dist/mqttPacket/pubcomp.js +0 -20
  85. package/dist/mqttPacket/publish.js +0 -51
  86. package/dist/mqttPacket/pubrec.js +0 -20
  87. package/dist/mqttPacket/pubrel.js +0 -20
  88. package/dist/mqttPacket/suback.js +0 -29
  89. package/dist/mqttPacket/subscribe.js +0 -52
  90. package/dist/mqttPacket/types.js +0 -1
  91. package/dist/mqttPacket/unsuback.js +0 -20
  92. package/dist/mqttPacket/unsubscribe.js +0 -36
  93. package/dist/mqttPacket/validators.js +0 -15
  94. package/dist/node/tcpClient.js +0 -81
  95. package/dist/node/tcpServer.js +0 -43
  96. package/dist/node/wrapNodeSocket.js +0 -47
  97. package/dist/persistence/deps.js +0 -3
  98. package/dist/persistence/memory/memoryPersistence.js +0 -117
  99. package/dist/persistence/persistence.js +0 -1
  100. package/dist/persistence/store.js +0 -1
  101. package/dist/server/context.js +0 -100
  102. package/dist/server/deps.js +0 -5
  103. package/dist/server/handlers/handleConnect.js +0 -46
  104. package/dist/server/handlers/handleDisconnect.js +0 -4
  105. package/dist/server/handlers/handlePacket.js +0 -58
  106. package/dist/server/handlers/handlePingreq.js +0 -6
  107. package/dist/server/handlers/handlePuback.js +0 -8
  108. package/dist/server/handlers/handlePubcomp.js +0 -8
  109. package/dist/server/handlers/handlePublish.js +0 -41
  110. package/dist/server/handlers/handlePubrec.js +0 -15
  111. package/dist/server/handlers/handlePubrel.js +0 -18
  112. package/dist/server/handlers/handleSubscribe.js +0 -33
  113. package/dist/server/handlers/handleUnsubscribe.js +0 -12
  114. package/dist/server/mod.js +0 -7
  115. package/dist/server/server.js +0 -47
  116. package/dist/socket/socket.js +0 -36
  117. package/dist/timer/timer.js +0 -40
  118. package/dist/trie/trie.js +0 -95
  119. package/dist/tsconfig.tsbuildinfo +0 -1
  120. package/dist/utils/args.js +0 -75
  121. package/dist/utils/assert.js +0 -20
  122. package/dist/utils/asyncQueue.js +0 -67
  123. package/dist/utils/deferred.js +0 -14
  124. package/dist/utils/logger.js +0 -58
  125. package/dist/utils/mod.js +0 -11
  126. package/dist/utils/nextTick.js +0 -6
  127. package/dist/utils/platform.js +0 -7
  128. package/tsconfig.json +0 -22
package/dist/bin/mqtt.js DELETED
@@ -1,227 +0,0 @@
1
- #!/usr/bin/env -S node --experimental-strip-types
2
- import { DEFAULT_URL } from "../client/mod.js";
3
- import { getFileData, TcpClient } from "../node/tcpClient.js";
4
- import { getArgs, logger, LogLevel, parseArgs } from "../utils/mod.js";
5
- const client = new TcpClient();
6
- const encoder = new TextEncoder();
7
- const decoder = new TextDecoder();
8
- logger.level(LogLevel.info);
9
- const MQTTHelp = `MQTT command line interface, available commands are:
10
-
11
- * publish publish a message to the broker
12
- * subscribe subscribe for updates from the broker
13
-
14
- Run 'mqtt [command] --help' to know more about the commands.`;
15
- const ConnectHelp = `
16
- -u/--url the URL to connect to: default is ${DEFAULT_URL}
17
- -i/--clientId the clientId to connect to the server
18
- -U/--username the username to connect to the server
19
- -P/--password the password to connect to the server
20
- -C/--caFile the path to a CA certificate file
21
- -c/--certFile the path to a certificate file
22
- -k/--keyFile the path to a key file
23
- -n/--noClean try to resume a previous session
24
- -h/--help this text
25
- `;
26
- const connectOpts = {
27
- string: [
28
- "url",
29
- "username",
30
- "password",
31
- "caFile",
32
- "certFile",
33
- "keyFile",
34
- "clientId",
35
- ],
36
- alias: {
37
- u: "url",
38
- U: "username",
39
- P: "password",
40
- C: "caFile",
41
- c: "certFile",
42
- k: "keyFile",
43
- i: "clientId",
44
- n: "noClean",
45
- h: "help",
46
- },
47
- boolean: ["noClean", "help"],
48
- default: {
49
- noClean: false,
50
- clientId: `Opifex-${crypto.randomUUID()}`,
51
- },
52
- };
53
- const SubscribeHelp = `Usage: mqtt subscribe <options>
54
-
55
- Where options are:
56
- -t/--topic the topic to use
57
- -q/--qos the QoS (0/1/2) to use, default is 0
58
- ${ConnectHelp}
59
- Example: mqtt subscribe -t hello`;
60
- const subscribeOpts = {
61
- string: ["topic"],
62
- alias: {
63
- t: "topic",
64
- q: "qos",
65
- },
66
- default: {
67
- qos: 0,
68
- topic: "",
69
- },
70
- };
71
- function parseQos(qosArg) {
72
- const qos = Number(qosArg);
73
- switch (qos) {
74
- case 0:
75
- return 0;
76
- case 1:
77
- return 1;
78
- case 2:
79
- return 2;
80
- default:
81
- break;
82
- }
83
- console.log("QoS must be between 0 and 2");
84
- return 0;
85
- }
86
- async function getTLSdata(connectArgs) {
87
- const caFileData = await getFileData(connectArgs.caFile);
88
- const caCerts = caFileData ? [caFileData] : undefined;
89
- const cert = await getFileData(connectArgs.certFile);
90
- const key = await getFileData(connectArgs.keyFile);
91
- return {
92
- caCerts,
93
- cert,
94
- key,
95
- };
96
- }
97
- async function subscribe() {
98
- const connectArgs = parseArgs(getArgs(), connectOpts);
99
- const { caCerts, cert, key, } = await getTLSdata(connectArgs);
100
- const subscribeArgs = parseArgs(getArgs(), subscribeOpts);
101
- if (connectArgs.help) {
102
- console.log(SubscribeHelp);
103
- return;
104
- }
105
- if (subscribeArgs.topic === undefined) {
106
- console.log("Missing `topic`");
107
- return;
108
- }
109
- try {
110
- await client.connect({
111
- url: connectArgs.url,
112
- caCerts,
113
- cert,
114
- key,
115
- options: {
116
- username: connectArgs.username,
117
- password: encoder.encode(connectArgs.password),
118
- clientId: connectArgs.clientId,
119
- clean: !connectArgs.noClean,
120
- keepAlive: 60,
121
- },
122
- });
123
- logger.debug("Connected !");
124
- client.subscribe({
125
- subscriptions: [
126
- {
127
- topicFilter: subscribeArgs.topic,
128
- qos: parseQos(subscribeArgs.qos),
129
- },
130
- ],
131
- });
132
- logger.debug("Subscribed!");
133
- for await (const message of client.messages()) {
134
- console.log(decoder.decode(message.payload));
135
- }
136
- }
137
- catch (err) {
138
- if (err instanceof Error) {
139
- // @ts-ignore the type spec of err is missing err.code
140
- logger.info(`Error: ${err.message || err.code}`);
141
- }
142
- }
143
- }
144
- const PublishHelp = `Usage: mqtt publish <options>
145
-
146
- Where options are:
147
- -t/--topic the topic to use
148
- -m/--message the message to send
149
- -q/--qos the QoS (0/1/2) to use, default is 0
150
- -r/--retain if the message should be retained, default is false
151
- ${ConnectHelp}
152
- Example: mqtt publish -t hello -m world`;
153
- const publishOpts = {
154
- string: ["topic", "message"],
155
- boolean: ["retain"],
156
- alias: {
157
- t: "topic",
158
- m: "message",
159
- q: "qos",
160
- r: "retain",
161
- },
162
- default: {
163
- qos: 0,
164
- dup: false,
165
- retain: false,
166
- topic: undefined,
167
- message: "",
168
- },
169
- };
170
- async function publish() {
171
- const connectArgs = parseArgs(getArgs(), connectOpts);
172
- const { caCerts, cert, key, } = await getTLSdata(connectArgs);
173
- const publishArgs = parseArgs(getArgs(), publishOpts);
174
- if (connectArgs.help) {
175
- console.log(PublishHelp);
176
- return;
177
- }
178
- if (publishArgs.topic === undefined) {
179
- console.log("Missing `topic`");
180
- return;
181
- }
182
- try {
183
- await client.connect({
184
- url: connectArgs.url,
185
- caCerts,
186
- cert,
187
- key,
188
- options: {
189
- username: connectArgs.username,
190
- password: encoder.encode(connectArgs.password),
191
- clientId: connectArgs.clientId,
192
- clean: !connectArgs.noClean,
193
- },
194
- });
195
- logger.debug("Connected !");
196
- await client.publish({
197
- topic: publishArgs.topic,
198
- payload: encoder.encode(publishArgs.message),
199
- retain: publishArgs.retain,
200
- qos: parseQos(publishArgs.qos),
201
- });
202
- logger.debug("Published!");
203
- client.disconnect();
204
- logger.debug("Disconnected !");
205
- }
206
- catch (err) {
207
- if (err instanceof Error) {
208
- // @ts-ignore the type spec of err is missing err.code
209
- logger.info(`Error: ${err.message || err.code}`);
210
- }
211
- }
212
- }
213
- function processArgs() {
214
- const { _: [cmd] } = parseArgs(getArgs());
215
- switch (cmd) {
216
- case "publish":
217
- publish();
218
- break;
219
- case "subscribe":
220
- subscribe();
221
- break;
222
- default:
223
- console.log(MQTTHelp);
224
- break;
225
- }
226
- }
227
- processArgs();
@@ -1,7 +0,0 @@
1
- export const ConnectionState = {
2
- offline: "offline",
3
- connecting: "connecting",
4
- connected: "connected",
5
- disconnecting: "disconnecting",
6
- disconnected: "disconnected",
7
- };
@@ -1,132 +0,0 @@
1
- import { Deferred, logger, MemoryStore, PacketType, } from "./deps.js";
2
- import { Context } from "./context.js";
3
- function generateClientId(prefix) {
4
- return `${prefix}-${Math.random().toString().slice(-10)}`;
5
- }
6
- function backOffSleep(random, attempt) {
7
- // based on https://dthain.blogspot.com/2009/02/exponential-backoff-in-distributed.html
8
- const factor = 1.5;
9
- const min = 1000;
10
- const max = 5000;
11
- const randomness = 1 + (random ? Math.random() : 0);
12
- const delay = Math.floor(Math.min(randomness * min * (factor ** attempt), max));
13
- logger.debug({ delay });
14
- return new Promise((resolve) => setTimeout(resolve, delay));
15
- }
16
- /** the default MQTT URL to connect to */
17
- export const DEFAULT_URL = "mqtt://localhost:1883/";
18
- const DEFAULT_KEEPALIVE = 60; // 60 seconds
19
- const DEFAULT_RETRIES = 3; // on first connect
20
- const CLIENTID_PREFIX = "opifex"; // on first connect
21
- /**
22
- * The Client class provides an MQTT Client that can be used to connect to
23
- * a MQTT broker and publish/subscribe messages.
24
- *
25
- * The Client class is not meant to be used directly, but
26
- * instead should be subclassed and the subclass should
27
- * override the createConn() method to provide a
28
- * connection type that is supported by the subclass.
29
- */
30
- export class Client {
31
- clientIdPrefix = CLIENTID_PREFIX;
32
- numberOfRetries = DEFAULT_RETRIES;
33
- url = new URL(DEFAULT_URL);
34
- keepAlive = DEFAULT_KEEPALIVE;
35
- autoReconnect = true;
36
- caCerts;
37
- cert;
38
- key;
39
- clientId;
40
- ctx = new Context(new MemoryStore());
41
- connectPacket;
42
- constructor() {
43
- this.clientId = generateClientId(this.clientIdPrefix);
44
- this.numberOfRetries = DEFAULT_RETRIES;
45
- }
46
- createConn(protocol, _hostname, _port, _caCerts, _cert, _key) {
47
- // if you need to support alternative connection types just
48
- // overload this method in your subclass
49
- throw `Unsupported protocol: ${protocol}`;
50
- }
51
- async doConnect() {
52
- if (!this.connectPacket) {
53
- return;
54
- }
55
- let isReconnect = false;
56
- let attempt = 1;
57
- let lastMessage = new Error();
58
- let tryConnect = true;
59
- while (tryConnect) {
60
- logger.debug(`${isReconnect ? "re" : ""}connecting`);
61
- try {
62
- const conn = await this.createConn(this.url.protocol, this.url.hostname, Number(this.url.port) ?? undefined, this.caCerts, this.cert, this.key);
63
- // if we get this far we have a connection
64
- tryConnect =
65
- (await this.ctx.handleConnection(conn, this.connectPacket)) &&
66
- this.autoReconnect;
67
- logger.debug({ tryConnect });
68
- isReconnect = true;
69
- this.connectPacket.clean = false;
70
- this.ctx.close();
71
- }
72
- catch (err) {
73
- if (err instanceof Error) {
74
- lastMessage = err;
75
- }
76
- logger.debug(lastMessage);
77
- if (!isReconnect && attempt > this.numberOfRetries) {
78
- tryConnect = false;
79
- }
80
- else {
81
- await backOffSleep(true, attempt++);
82
- }
83
- }
84
- }
85
- if (isReconnect === false) {
86
- this.ctx.unresolvedConnect?.reject(lastMessage);
87
- }
88
- }
89
- connect(params = {}) {
90
- this.url = params?.url || this.url;
91
- this.numberOfRetries = params.numberOfRetries || this.numberOfRetries;
92
- this.caCerts = params?.caCerts;
93
- this.cert = params?.cert;
94
- this.key = params?.key;
95
- const options = Object.assign({
96
- keepAlive: this.keepAlive,
97
- clientId: this.clientId,
98
- }, params?.options);
99
- this.connectPacket = {
100
- type: PacketType.connect,
101
- ...options,
102
- };
103
- const deferred = new Deferred();
104
- this.ctx.unresolvedConnect = deferred;
105
- this.doConnect();
106
- return deferred.promise;
107
- }
108
- async disconnect() {
109
- await this.ctx.disconnect();
110
- }
111
- async publish(params) {
112
- const packet = {
113
- type: PacketType.publish,
114
- ...params,
115
- };
116
- await this.ctx.publish(packet);
117
- }
118
- async subscribe(params) {
119
- const packet = {
120
- type: PacketType.subscribe,
121
- id: 0, //placeholder
122
- ...params,
123
- };
124
- await this.ctx.subscribe(packet);
125
- }
126
- async *messages() {
127
- yield* this.ctx.incoming;
128
- }
129
- closeMessages(reason) {
130
- this.ctx.incoming.close(reason);
131
- }
132
- }
@@ -1,148 +0,0 @@
1
- import { AsyncQueue, Deferred, logger, MqttConn, PacketType, Timer, } from "./deps.js";
2
- import { handlePacket } from "./handlers/handlePacket.js";
3
- import { ConnectionState } from "./ConnectionState.js";
4
- export class Context {
5
- mqttConn;
6
- connectionState;
7
- pingTimer;
8
- unresolvedConnect;
9
- unresolvedPublish;
10
- unresolvedSubscribe;
11
- unresolvedUnSubscribe;
12
- store;
13
- incoming;
14
- constructor(store) {
15
- this.store = store;
16
- this.connectionState = ConnectionState.offline;
17
- this.incoming = new AsyncQueue();
18
- this.unresolvedPublish = new Map();
19
- this.unresolvedSubscribe = new Map();
20
- this.unresolvedUnSubscribe = new Map();
21
- }
22
- async connect(packet) {
23
- this.connectionState = ConnectionState.connecting;
24
- await this.mqttConn?.send(packet);
25
- const keepAlive = packet.keepAlive || 0;
26
- if (keepAlive > 0) {
27
- this.pingTimer = new Timer(this.sendPing.bind(this), keepAlive * 1000, true);
28
- }
29
- }
30
- async disconnect() {
31
- if (this.connectionState !== ConnectionState.connected) {
32
- throw "Not connected";
33
- }
34
- if (this.mqttConn) {
35
- this.connectionState = ConnectionState.disconnecting;
36
- await this.mqttConn.send({ type: PacketType.disconnect });
37
- this.mqttConn.close();
38
- }
39
- }
40
- async send(packet) {
41
- logger.debug({ send: packet });
42
- if (this.connectionState === ConnectionState.connected &&
43
- !this.mqttConn?.isClosed) {
44
- await this.mqttConn?.send(packet);
45
- this.pingTimer?.reset();
46
- return;
47
- }
48
- logger.debug("not connected");
49
- this.pingTimer?.clear();
50
- }
51
- sendPing() {
52
- this.send({ type: PacketType.pingreq });
53
- }
54
- async handleConnection(conn, connectPacket) {
55
- this.mqttConn = new MqttConn({ conn });
56
- if (this.mqttConn === undefined) {
57
- return true;
58
- }
59
- logger.debug("Send connect packet");
60
- await this.connect(connectPacket);
61
- try {
62
- logger.debug("Accepting packets");
63
- for await (const packet of this.mqttConn) {
64
- handlePacket(this, packet);
65
- }
66
- logger.debug("No more packets");
67
- }
68
- catch (err) {
69
- logger.debug(err);
70
- if (this.mqttConn.isClosed) {
71
- this.mqttConn.close();
72
- }
73
- }
74
- if (this.connectionState === ConnectionState.disconnecting) {
75
- return false;
76
- }
77
- return true;
78
- }
79
- close() {
80
- logger.debug("closing connection");
81
- this.connectionState = ConnectionState.disconnected;
82
- this.pingTimer?.clear();
83
- }
84
- receivePublish(packet) {
85
- this.incoming.push(packet);
86
- }
87
- publish(packet) {
88
- const qos = packet.qos || 0;
89
- if (qos === 0) {
90
- packet.id = 0;
91
- this.send(packet);
92
- // return empty promise
93
- return Promise.resolve();
94
- }
95
- packet.id = this.store.nextId();
96
- this.store.pendingOutgoing.set(packet.id, packet);
97
- const deferred = new Deferred();
98
- this.unresolvedPublish.set(packet.id, deferred);
99
- this.send(packet);
100
- return deferred.promise;
101
- }
102
- subscribe(packet) {
103
- packet.id = this.store.nextId();
104
- this.store.pendingOutgoing.set(packet.id, packet);
105
- const deferred = new Deferred();
106
- this.unresolvedSubscribe.set(packet.id, deferred);
107
- this.send(packet);
108
- return deferred.promise;
109
- }
110
- unsubscribe(packet) {
111
- packet.id = this.store.nextId();
112
- this.store.pendingOutgoing.set(packet.id, packet);
113
- const deferred = new Deferred();
114
- this.unresolvedUnSubscribe.set(packet.id, deferred);
115
- this.send(packet);
116
- return deferred.promise;
117
- }
118
- receivePuback(id) {
119
- const unresolvedMap = this.unresolvedPublish;
120
- if (unresolvedMap.has(id)) {
121
- const deferred = unresolvedMap.get(id);
122
- unresolvedMap.delete(id);
123
- deferred?.resolve();
124
- return true;
125
- }
126
- return false;
127
- }
128
- receiveSuback(id, returnCodes) {
129
- const unresolvedMap = this.unresolvedSubscribe;
130
- if (unresolvedMap.has(id)) {
131
- const deferred = unresolvedMap.get(id);
132
- unresolvedMap.delete(id);
133
- deferred?.resolve(returnCodes);
134
- return true;
135
- }
136
- return false;
137
- }
138
- receiveUnsuback(id) {
139
- const unresolvedMap = this.unresolvedUnSubscribe;
140
- if (unresolvedMap.has(id)) {
141
- const deferred = unresolvedMap.get(id);
142
- unresolvedMap.delete(id);
143
- deferred?.resolve();
144
- return true;
145
- }
146
- return false;
147
- }
148
- }
@@ -1,5 +0,0 @@
1
- export { AuthenticationResult, AuthenticationResultByNumber, decodePayload, encode, PacketNameByType, PacketType, } from "../mqttPacket/mod.js";
2
- export { MqttConn } from "../mqttConn/mqttConn.js";
3
- export { Timer } from "../timer/timer.js";
4
- export { AsyncQueue, Deferred, logger } from "../utils/mod.js";
5
- export { MemoryStore } from "./store/memoryStore.js";
@@ -1,18 +0,0 @@
1
- import { ConnectionState } from "../ConnectionState.js";
2
- import { AuthenticationResultByNumber } from "../deps.js";
3
- export async function handleConnack(packet, ctx) {
4
- if (packet.returnCode === 0) {
5
- ctx.connectionState = ConnectionState.connected;
6
- ctx.pingTimer?.reset();
7
- ctx.unresolvedConnect?.resolve(packet.returnCode);
8
- // start transmitting packets that were queued before
9
- for await (const packet of ctx.store.pendingOutgoingPackets()) {
10
- ctx.send(packet);
11
- }
12
- return;
13
- }
14
- const err = new Error(`Connect failed: ${AuthenticationResultByNumber[packet.returnCode]}`);
15
- ctx.connectionState = ConnectionState.disconnecting;
16
- ctx.pingTimer?.clear();
17
- ctx.unresolvedConnect?.reject(err);
18
- }
@@ -1,50 +0,0 @@
1
- import { ConnectionState } from "../ConnectionState.js";
2
- import { handleConnack } from "./handleConnack.js";
3
- import { handlePublish } from "./handlePublish.js";
4
- import { handlePuback } from "./handlePuback.js";
5
- import { handlePubrec } from "./handlePubrec.js";
6
- import { handlePubrel } from "./handlePubrel.js";
7
- import { handlePubcomp } from "./handlePubcomp.js";
8
- import { handleSuback } from "./handleSuback.js";
9
- import { handleUnsuback } from "./handleUnsuback.js";
10
- import { logger, PacketNameByType, PacketType } from "../deps.js";
11
- export async function handlePacket(ctx, packet) {
12
- logger.debug({ received: PacketNameByType[packet.type], packet });
13
- if (ctx.connectionState !== ConnectionState.connected) {
14
- if (packet.type === PacketType.connack) {
15
- handleConnack(packet, ctx);
16
- }
17
- else {
18
- throw new Error(`Received ${PacketNameByType[packet.type]} packet before connect`);
19
- }
20
- }
21
- else {
22
- switch (packet.type) {
23
- case PacketType.pingres:
24
- break;
25
- case PacketType.publish:
26
- await handlePublish(ctx, packet);
27
- break;
28
- case PacketType.puback:
29
- await handlePuback(ctx, packet);
30
- break;
31
- case PacketType.pubrel:
32
- await handlePubrel(ctx, packet);
33
- break;
34
- case PacketType.pubrec:
35
- await handlePubrec(ctx, packet);
36
- break;
37
- case PacketType.pubcomp:
38
- await handlePubcomp(ctx, packet);
39
- break;
40
- case PacketType.suback:
41
- await handleSuback(ctx, packet);
42
- break;
43
- case PacketType.unsuback:
44
- handleUnsuback(ctx, packet);
45
- break;
46
- default:
47
- throw new Error(`Received unexpected ${PacketNameByType[packet.type]} packet after connect`);
48
- }
49
- }
50
- }
@@ -1,6 +0,0 @@
1
- // A PUBACK Packet is the response to a PUBLISH Packet with QoS level 1.
2
- export function handlePuback(ctx, packet) {
3
- const id = packet.id;
4
- ctx.store.pendingOutgoing.delete(id);
5
- ctx.receivePuback(id);
6
- }
@@ -1,9 +0,0 @@
1
- // The PUBCOMP Packet is the response to a PUBREL Packet.
2
- // It is the fourth and final packet of the QoS 2 protocol exchange.
3
- export function handlePubcomp(ctx, packet) {
4
- const id = packet.id;
5
- if (ctx.store.pendingAckOutgoing.has(id)) {
6
- ctx.store.pendingAckOutgoing.delete(id);
7
- ctx.receivePuback(id);
8
- }
9
- }
@@ -1,28 +0,0 @@
1
- import { PacketType } from "../deps.js";
2
- // Incoming publish
3
- export async function handlePublish(ctx, packet) {
4
- const qos = packet.qos || 0;
5
- if (qos === 0) {
6
- ctx.receivePublish(packet);
7
- return;
8
- }
9
- if (packet.id !== undefined) {
10
- // qos 1
11
- if (qos === 1) {
12
- ctx.receivePublish(packet);
13
- await ctx.send({
14
- type: PacketType.puback,
15
- id: packet.id,
16
- });
17
- return;
18
- }
19
- // qos 2
20
- if (ctx.store) {
21
- ctx.store.pendingIncoming.set(packet.id, packet);
22
- await ctx.send({
23
- type: PacketType.pubrec,
24
- id: packet.id,
25
- });
26
- }
27
- }
28
- }
@@ -1,17 +0,0 @@
1
- import { PacketType } from "../deps.js";
2
- // A PUBREC Packet is the response to a PUBLISH Packet with QoS 2.
3
- // It is the second packet of the QoS 2 protocol exchange.
4
- // Discard message, Store PUBREC received <Packet Identifier>
5
- // send PUBREL <Packet Identifier>
6
- export async function handlePubrec(ctx, packet) {
7
- const id = packet.id;
8
- const ack = {
9
- type: PacketType.pubrel,
10
- id,
11
- };
12
- if (ctx.store.pendingOutgoing.has(id)) {
13
- ctx.store.pendingAckOutgoing.set(id, ack);
14
- ctx.store.pendingOutgoing.delete(id);
15
- await ctx.send(ack);
16
- }
17
- }
@@ -1,19 +0,0 @@
1
- import { PacketType } from "../deps.js";
2
- // A PUBREL Packet is the response to a PUBREC Packet.
3
- // It is the third packet of the QoS 2 protocol exchange.
4
- // Method A, Initiate onward delivery of the Application Message then discard message
5
- // Send PUBCOMP <Packet Identifier>
6
- export async function handlePubrel(ctx, packet) {
7
- const id = packet.id;
8
- if (ctx.store.pendingIncoming.has(id)) {
9
- const storedPacket = ctx.store.pendingIncoming.get(id);
10
- if (storedPacket) {
11
- ctx.receivePublish(storedPacket);
12
- ctx.store.pendingIncoming.delete(id);
13
- await ctx.send({
14
- type: PacketType.pubcomp,
15
- id,
16
- });
17
- }
18
- }
19
- }
@@ -1,9 +0,0 @@
1
- // A SUBACK Packet is sent by the Server to the Client to confirm receipt
2
- // and processing of a SUBSCRIBE Packet.
3
- // A SUBACK Packet contains a list of return codes, that specify the maximum QoS level
4
- // that was granted in each Subscription that was requested by the SUBSCRIBE.
5
- export function handleSuback(ctx, packet) {
6
- const id = packet.id;
7
- ctx.store.pendingOutgoing.delete(id);
8
- ctx.receiveSuback(id, packet.returnCodes);
9
- }