@@ -36,21 +36,22 @@ Configure the plugin in the Dashboard: http://localhost:18083/#/plugins/detail/e
3636
3737Verify:
3838
39+ Using [ MQTTX CLI] ( https://mqttx.app/cli )
40+
3941``` bash
40- mosquitto_pub -d -q 1 -t ' t/2' -m ' hello-from-offline1'
41- mosquitto_pub -d -q 1 -t ' t/2' -m ' hello-from-offline2'
42- mosquitto_pub -d -q 1 -t ' t/2' -m ' hello-from-offline3'
42+ mqttx pub -q 1 -t ' t/2' -m ' hello-from-offline1'
43+ mqttx pub -q 1 -t ' t/2' -m ' hello-from-offline2'
44+ mqttx pub -q 1 -t ' t/2' -m ' hello-from-offline3'
4345
44- mosquitto_sub -d -q 1 -t ' t/2' -i $( pwgen 20 -1)
46+ mqttx sub -q 1 -t ' t/2' -i $( pwgen 20 -1)
4547```
4648
4749No messages should be received:
4850
4951``` bash
50- mosquitto_sub -d -q 1 -t ' t/2' -i $( pwgen 20 -1)
52+ mqttx sub -q 1 -t ' t/2' -i $( pwgen 20 -1)
5153```
5254
53-
5455## Release
5556
5657An EMQX plugin release is a tar file including including a subdirectory of this plugin's name and it's version, that contains:
@@ -72,3 +73,76 @@ make fmt
7273```
7374
7475See [ EMQX documentation] ( https://docs.emqx.com/en/enterprise/v5.0/extensions/plugins.html ) for details on how to deploy custom plugins.
76+
77+ ## Database Schema
78+
79+ This plugin requires a pre-defined database schema.
80+
81+ ### MySQL
82+
83+ ** Messages table**
84+
85+ ```
86+ CREATE TABLE IF NOT EXISTS `mqtt_msg` (
87+ `id` bigint unsigned NOT NULL AUTO_INCREMENT,
88+ `msgid` varchar(64) DEFAULT NULL,
89+ `topic` varchar(180) NOT NULL,
90+ `sender` varchar(64) DEFAULT NULL,
91+ `qos` tinyint(1) NOT NULL DEFAULT '0',
92+ `retain` tinyint(1) DEFAULT NULL,
93+ `payload` blob,
94+ `arrived` datetime NOT NULL,
95+ PRIMARY KEY (`id`),
96+ INDEX topic_index(`topic`)
97+ )
98+ ENGINE=InnoDB DEFAULT CHARSET=utf8MB4;
99+ ```
100+
101+ ** Subscriptions table**
102+
103+ ```
104+ CREATE TABLE IF NOT EXISTS `mqtt_sub` (
105+ `clientid` varchar(64) NOT NULL,
106+ `topic` varchar(180) NOT NULL,
107+ `qos` tinyint(1) NOT NULL DEFAULT '0',
108+ PRIMARY KEY (`clientid`, `topic`)
109+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8MB4;
110+ ```
111+
112+ ### Redis
113+
114+ Redis uses the following data structures (no predefined schema needed, structures are created automatically):
115+
116+ ** Subscriptions** - Redis Hashes
117+
118+ - Key pattern: ` mqtt:sub:{clientid} `
119+ - Hash fields: ` {topic} ` -> ` {qos} ` (integer)
120+ - Operations: ` HSET ` , ` HDEL ` , ` HGETALL `
121+
122+ ** Messages** - Redis Hashes
123+
124+ - Key pattern: ` mqtt:msg:{msgid} ` (msgid is base62 encoded)
125+ - Hash fields:
126+ - ` id ` -> base62 encoded message ID
127+ - ` from ` -> sender/clientid
128+ - ` qos ` -> QoS level (0, 1, or 2)
129+ - ` topic ` -> topic name
130+ - ` payload ` -> message payload (binary)
131+ - ` ts ` -> timestamp (integer)
132+ - ` retain ` -> "true" or "false" (string)
133+ - Operations: ` HMSET ` , ` HGETALL ` , ` DEL ` , ` EXPIRE `
134+
135+ ** Message Index by Topic** - Redis Sorted Sets
136+
137+ - Key pattern: ` mqtt:msg:{topic} `
138+ - Members: base62 encoded message IDs
139+ - Scores: timestamps (used for TTL/expiration cleanup)
140+ - Operations: ` ZADD ` , ` ZRANGE ` , ` ZREMRANGEBYSCORE ` , ` ZREM `
141+
142+ ** Required Redis Operations for ACL Control**
143+
144+ If using Redis ACL, the user needs permissions for the following operations:
145+
146+ - Hash operations: ` HSET ` , ` HDEL ` , ` HGETALL ` , ` HMSET ` , ` DEL ` , ` EXPIRE `
147+ - Sorted set operations: ` ZADD ` , ` ZRANGE ` , ` ZREMRANGEBYSCORE ` , ` ZREM `
148+ - Key pattern operations: Access to keys matching ` mqtt:sub:* ` and ` mqtt:msg:* `
0 commit comments