@seriousme/opifex 1.11.1 → 1.11.3
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/LICENSE.txt +1 -1
- package/README.md +8 -8
- package/benchmarks/receiver.ts +35 -0
- package/benchmarks/sender.ts +32 -0
- package/benchmarks/utils.ts +8 -31
- package/bin/mqtt.ts +52 -30
- package/client/client.ts +9 -9
- package/client/deps.ts +1 -0
- package/client/mod.ts +1 -1
- package/dev_utils/mod.ts +1 -0
- package/dev_utils/socketPair.ts +85 -0
- package/dist/bin/mqtt.js +19 -16
- package/dist/bin/mqtt.js.map +1 -1
- package/dist/client/client.d.ts +6 -6
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js.map +1 -1
- package/dist/client/deps.d.ts +1 -1
- package/dist/client/deps.d.ts.map +1 -1
- package/dist/client/deps.js.map +1 -1
- package/dist/client/mod.d.ts +1 -1
- package/dist/client/mod.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.d.ts +2 -1
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +16 -8
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/BitMask.d.ts +12 -11
- package/dist/mqttPacket/BitMask.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.js +10 -18
- package/dist/mqttPacket/BitMask.js.map +1 -1
- package/dist/mqttPacket/connect.d.ts +22 -22
- package/dist/mqttPacket/connect.d.ts.map +1 -1
- package/dist/mqttPacket/decoder.js +1 -1
- package/dist/mqttPacket/decoder.js.map +1 -1
- package/dist/mqttPacket/length.js +1 -1
- package/dist/mqttPacket/length.js.map +1 -1
- package/dist/mqttPacket/mod.js +1 -1
- package/dist/mqttPacket/mod.js.map +1 -1
- package/dist/mqttPacket/pubblishAcks.d.ts +5 -5
- package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
- package/dist/mqttPacket/pubblishAcks.js.map +1 -1
- package/dist/mqttPacket/publish.d.ts +9 -9
- package/dist/mqttPacket/publish.d.ts.map +1 -1
- package/dist/persistence/memory/memoryPersistence.d.ts +3 -3
- package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
- package/dist/persistence/memory/memoryPersistence.js +1 -1
- package/dist/persistence/memory/memoryPersistence.js.map +1 -1
- package/dist/persistence/mod.d.ts +1 -1
- package/dist/persistence/mod.d.ts.map +1 -1
- package/dist/persistence/mod.js.map +1 -1
- package/dist/persistence/store.d.ts +3 -2
- package/dist/persistence/store.d.ts.map +1 -1
- package/dist/server/context.d.ts +1 -1
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js.map +1 -1
- package/dist/server/handlers/handlePublish.d.ts.map +1 -1
- package/dist/server/handlers/handlePublish.js +17 -2
- package/dist/server/handlers/handlePublish.js.map +1 -1
- package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrel.js +6 -10
- package/dist/server/handlers/handlePubrel.js.map +1 -1
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +4 -0
- package/dist/socket/socket.js.map +1 -1
- package/dist/trie/trie.d.ts.map +1 -1
- package/dist/trie/trie.js +30 -20
- package/dist/trie/trie.js.map +1 -1
- package/dist/utils/BufferedAsyncIterable.js.map +1 -1
- package/mqttConn/mqttConn.ts +18 -8
- package/mqttPacket/BitMask.ts +11 -19
- package/mqttPacket/connect.ts +22 -22
- package/mqttPacket/decoder.ts +1 -1
- package/mqttPacket/length.ts +1 -1
- package/mqttPacket/mod.ts +1 -1
- package/mqttPacket/pubblishAcks.ts +16 -11
- package/mqttPacket/publish.ts +9 -9
- package/package.json +3 -3
- package/persistence/memory/memoryPersistence.ts +4 -3
- package/persistence/mod.ts +6 -1
- package/persistence/store.ts +3 -2
- package/server/context.ts +1 -1
- package/server/handlers/handlePublish.ts +18 -2
- package/server/handlers/handlePubrel.ts +6 -10
- package/server/test/handleConnect.test.ts +13 -21
- package/socket/socket.ts +3 -0
- package/trie/trie.ts +29 -19
- package/utils/BufferedAsyncIterable.ts +1 -1
- package/benchmarks/bombing.ts +0 -35
- package/benchmarks/throughputCounter.ts +0 -31
|
@@ -52,9 +52,25 @@ export async function handlePublish(
|
|
|
52
52
|
});
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
|
|
56
|
+
/*
|
|
57
|
+
In the QoS 2 delivery protocol, the Receiver
|
|
58
|
+
|
|
59
|
+
- MUST respond with a PUBREC containing the Packet Identifier from the incoming PUBLISH Packet,
|
|
60
|
+
having accepted ownership of the Application Message.
|
|
61
|
+
- Until it has received the corresponding PUBREL packet, the Receiver MUST acknowledge any subsequent
|
|
62
|
+
PUBLISH packet with the same Packet Identifier by sending a PUBREC. It MUST NOT cause duplicate
|
|
63
|
+
messages to be delivered to any onward recipients in this case.
|
|
64
|
+
- MUST respond to a PUBREL packet by sending a PUBCOMP packet containing the same Packet Identifier as the PUBREL.
|
|
65
|
+
- After it has sent a PUBCOMP, the receiver MUST treat any subsequent PUBLISH packet that contains that Packet
|
|
66
|
+
Identifier as being a new publication.
|
|
67
|
+
[MQTT-4.3.3-2].
|
|
68
|
+
*/
|
|
56
69
|
if (ctx.store) {
|
|
57
|
-
ctx.store.pendingIncoming.
|
|
70
|
+
if (!ctx.store.pendingIncoming.has(packet.id)) {
|
|
71
|
+
ctx.persistence.publish(packet.topic, packet);
|
|
72
|
+
ctx.store.pendingIncoming.add(packet.id);
|
|
73
|
+
}
|
|
58
74
|
await ctx.send({
|
|
59
75
|
type: PacketType.pubrec,
|
|
60
76
|
protocolLevel: ctx.protocolLevel,
|
|
@@ -20,15 +20,11 @@ export async function handlePubrel(
|
|
|
20
20
|
): Promise<void> {
|
|
21
21
|
const id = packet.id;
|
|
22
22
|
if (ctx.store?.pendingIncoming.has(id)) {
|
|
23
|
-
|
|
24
|
-
if (storedPacket) {
|
|
25
|
-
ctx.persistence.publish(storedPacket.topic, storedPacket);
|
|
26
|
-
ctx.store.pendingIncoming.delete(id);
|
|
27
|
-
await ctx.send({
|
|
28
|
-
type: PacketType.pubcomp,
|
|
29
|
-
protocolLevel: ctx.protocolLevel,
|
|
30
|
-
id,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
23
|
+
ctx.store.pendingIncoming.delete(id);
|
|
33
24
|
}
|
|
25
|
+
await ctx.send({
|
|
26
|
+
type: PacketType.pubcomp,
|
|
27
|
+
protocolLevel: ctx.protocolLevel,
|
|
28
|
+
id,
|
|
29
|
+
});
|
|
34
30
|
}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { test } from "node:test";
|
|
3
|
-
import {
|
|
4
|
-
makeDummyQueueSockConn,
|
|
5
|
-
resolveNextTick,
|
|
6
|
-
} from "../../dev_utils/mod.ts";
|
|
3
|
+
import { createWebSocketPair, resolveNextTick } from "../../dev_utils/mod.ts";
|
|
7
4
|
import {
|
|
8
5
|
type AnyPacket,
|
|
9
6
|
AuthenticationResult,
|
|
10
7
|
PacketType,
|
|
11
8
|
} from "../../mqttPacket/mod.ts";
|
|
12
|
-
import { BufferedAsyncIterable } from "../../utils/mod.ts";
|
|
13
9
|
import { MqttConn, MQTTLevel } from "../deps.ts";
|
|
14
10
|
import { MqttServer } from "../mod.ts";
|
|
15
11
|
import { handlers } from "./test-handlers.ts";
|
|
@@ -37,25 +33,21 @@ const disconnectPacket: AnyPacket = {
|
|
|
37
33
|
const mqttServer = new MqttServer({ handlers });
|
|
38
34
|
|
|
39
35
|
function startServer(): {
|
|
40
|
-
reader: AsyncIterator<AnyPacket>;
|
|
41
36
|
mqttConn: MqttConn;
|
|
42
37
|
} {
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const outputConn = makeDummyQueueSockConn(writer, reader);
|
|
47
|
-
const mqttConn = new MqttConn({ conn: outputConn });
|
|
48
|
-
const inputConn = makeDummyQueueSockConn(reader, writer, () => {
|
|
38
|
+
const { input, output } = createWebSocketPair();
|
|
39
|
+
const mqttConn = new MqttConn({ conn: output });
|
|
40
|
+
input.close = () => {
|
|
49
41
|
mqttConn.close();
|
|
50
|
-
}
|
|
51
|
-
mqttServer.serve(
|
|
52
|
-
return {
|
|
42
|
+
};
|
|
43
|
+
mqttServer.serve(input);
|
|
44
|
+
return { mqttConn };
|
|
53
45
|
}
|
|
54
46
|
|
|
55
47
|
test("Authentication with valid username and password works", async () => {
|
|
56
|
-
const {
|
|
48
|
+
const { mqttConn } = startServer();
|
|
57
49
|
mqttConn.send(connectPacket);
|
|
58
|
-
const { value: connack } = await
|
|
50
|
+
const { value: connack } = await mqttConn.next();
|
|
59
51
|
assert.deepStrictEqual(
|
|
60
52
|
connack.type,
|
|
61
53
|
PacketType.connack,
|
|
@@ -80,9 +72,9 @@ test("Authentication with valid username and password works", async () => {
|
|
|
80
72
|
test("Authentication with invalid username fails", async () => {
|
|
81
73
|
const newPacket = Object.assign({}, connectPacket);
|
|
82
74
|
newPacket.username = "wrong";
|
|
83
|
-
const {
|
|
75
|
+
const { mqttConn } = startServer();
|
|
84
76
|
mqttConn.send(newPacket);
|
|
85
|
-
const { value: connack } = await
|
|
77
|
+
const { value: connack } = await mqttConn.next();
|
|
86
78
|
assert.deepStrictEqual(
|
|
87
79
|
connack.type,
|
|
88
80
|
PacketType.connack,
|
|
@@ -106,9 +98,9 @@ test("Authentication with invalid username fails", async () => {
|
|
|
106
98
|
test("Authentication with invalid password fails", async () => {
|
|
107
99
|
const newPacket = Object.assign({}, connectPacket);
|
|
108
100
|
newPacket.password = undefined;
|
|
109
|
-
const {
|
|
101
|
+
const { mqttConn } = startServer();
|
|
110
102
|
mqttConn.send(newPacket);
|
|
111
|
-
const { value: connack } = await
|
|
103
|
+
const { value: connack } = await mqttConn.next();
|
|
112
104
|
assert.deepStrictEqual(
|
|
113
105
|
connack.type,
|
|
114
106
|
PacketType.connack,
|
package/socket/socket.ts
CHANGED
package/trie/trie.ts
CHANGED
|
@@ -46,7 +46,7 @@ export class Trie<T> {
|
|
|
46
46
|
*/
|
|
47
47
|
match(key: string): T[] {
|
|
48
48
|
const parts = key.split(this.separator);
|
|
49
|
-
if (parts.length > 0 && parts[0]
|
|
49
|
+
if (parts.length > 0 && parts[0]?.charAt(0) === this.reservedPrefix) {
|
|
50
50
|
return this._matchPrefix(parts);
|
|
51
51
|
}
|
|
52
52
|
return this._match(parts);
|
|
@@ -62,7 +62,10 @@ export class Trie<T> {
|
|
|
62
62
|
return this.#value ? this.#value : [];
|
|
63
63
|
}
|
|
64
64
|
const [first, ...rest] = parts;
|
|
65
|
-
|
|
65
|
+
if (first !== undefined) {
|
|
66
|
+
return this.matchChild(first, rest);
|
|
67
|
+
}
|
|
68
|
+
return [];
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
/**
|
|
@@ -75,11 +78,14 @@ export class Trie<T> {
|
|
|
75
78
|
return this.#value ? this.#value : [];
|
|
76
79
|
}
|
|
77
80
|
const [first, ...rest] = parts;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
if (first !== undefined) {
|
|
82
|
+
const exact = this.matchChild(first, rest);
|
|
83
|
+
const single = this.matchChild(this.wildcardOne, rest);
|
|
84
|
+
const subtree = this.matchChild(this.wildcardSubtree, []);
|
|
85
|
+
const results = exact.concat(single, subtree);
|
|
86
|
+
return results;
|
|
87
|
+
}
|
|
88
|
+
return [];
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
/**
|
|
@@ -102,13 +108,15 @@ export class Trie<T> {
|
|
|
102
108
|
return;
|
|
103
109
|
}
|
|
104
110
|
const [first, ...rest] = parts;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
child
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
if (first !== undefined) {
|
|
112
|
+
const child = this.#children.get(first);
|
|
113
|
+
if (child instanceof Trie) {
|
|
114
|
+
child._add(rest, value);
|
|
115
|
+
} else {
|
|
116
|
+
const node = new Trie<T>(this.looseCompare);
|
|
117
|
+
this.#children.set(first, node);
|
|
118
|
+
node._add(rest, value);
|
|
119
|
+
}
|
|
112
120
|
}
|
|
113
121
|
return;
|
|
114
122
|
}
|
|
@@ -134,11 +142,13 @@ export class Trie<T> {
|
|
|
134
142
|
return;
|
|
135
143
|
}
|
|
136
144
|
const [first, ...rest] = parts;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
node
|
|
140
|
-
|
|
141
|
-
this.#children.
|
|
145
|
+
if (first !== undefined) {
|
|
146
|
+
const node = this.#children.get(first);
|
|
147
|
+
if (node) {
|
|
148
|
+
node._remove(rest, value);
|
|
149
|
+
if (node.#value.length === 0 && this.#children.size === 0) {
|
|
150
|
+
this.#children.delete(first);
|
|
151
|
+
}
|
|
142
152
|
}
|
|
143
153
|
}
|
|
144
154
|
}
|
package/benchmarks/bombing.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { loader } from "./utils.ts";
|
|
2
|
-
import { runAsap } from "../dev_utils/timers.ts";
|
|
3
|
-
|
|
4
|
-
loader((ClientClass) => {
|
|
5
|
-
const client = new ClientClass();
|
|
6
|
-
|
|
7
|
-
client.connect({
|
|
8
|
-
url: new URL("mqtt://127.0.0.1:1884"),
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
client.onConnected = () => {
|
|
12
|
-
const payload = new TextEncoder().encode("payload");
|
|
13
|
-
|
|
14
|
-
let sent = 0;
|
|
15
|
-
const interval = 5000;
|
|
16
|
-
|
|
17
|
-
const loop = () => {
|
|
18
|
-
sent++;
|
|
19
|
-
client.publish({ topic: "test", payload })
|
|
20
|
-
.then(() => runAsap(loop));
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
function count() {
|
|
24
|
-
console.log("sent/s", (sent / interval) * 1000);
|
|
25
|
-
sent = 0;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
setInterval(count, interval);
|
|
29
|
-
loop();
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
client.onError = (err) => {
|
|
33
|
-
console.log("client error", err);
|
|
34
|
-
};
|
|
35
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { loader } from "./utils.ts";
|
|
2
|
-
|
|
3
|
-
loader(async (ClientClass) => {
|
|
4
|
-
const client = new ClientClass();
|
|
5
|
-
|
|
6
|
-
await client.connect({
|
|
7
|
-
url: new URL("mqtt://127.0.0.1:1884"),
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
await client.subscribe({ subscriptions: [{ topicFilter: "test", qos: 0 }] });
|
|
11
|
-
|
|
12
|
-
let counter = 0;
|
|
13
|
-
const interval = 5000;
|
|
14
|
-
|
|
15
|
-
function count() {
|
|
16
|
-
console.log("received/s", (counter / interval) * 1000);
|
|
17
|
-
counter = 0;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
setInterval(count, interval);
|
|
21
|
-
|
|
22
|
-
// // Consume using a callback
|
|
23
|
-
// client.onPacket = async (packet) => {
|
|
24
|
-
// counter++;
|
|
25
|
-
// };
|
|
26
|
-
|
|
27
|
-
// Consume using an AsyncIterator
|
|
28
|
-
for await (const _ of client.messages()) {
|
|
29
|
-
counter++;
|
|
30
|
-
}
|
|
31
|
-
});
|