├── .gitignore
├── LICENSE
├── README.md
├── README_EN.md
├── mqtt-auth
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── cn
│ │ └── wizzer
│ │ └── iot
│ │ └── mqtt
│ │ └── server
│ │ └── auth
│ │ ├── service
│ │ └── AuthService.java
│ │ └── util
│ │ ├── PwdUtil.java
│ │ └── RsaKeyUtil.java
│ └── resources
│ └── keystore
│ └── auth-private.key
├── mqtt-broker
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── cn
│ │ └── wizzer
│ │ └── iot
│ │ └── mqtt
│ │ └── server
│ │ └── broker
│ │ ├── MainLauncher.java
│ │ ├── cluster
│ │ └── RedisCluster.java
│ │ ├── codec
│ │ └── MqttWebSocketCodec.java
│ │ ├── config
│ │ └── BrokerProperties.java
│ │ ├── handler
│ │ └── BrokerHandler.java
│ │ ├── internal
│ │ ├── InternalCommunication.java
│ │ ├── InternalMessage.java
│ │ └── InternalSendServer.java
│ │ ├── protocol
│ │ ├── Connect.java
│ │ ├── DisConnect.java
│ │ ├── PingReq.java
│ │ ├── ProtocolProcess.java
│ │ ├── PubAck.java
│ │ ├── PubComp.java
│ │ ├── PubRec.java
│ │ ├── PubRel.java
│ │ ├── Publish.java
│ │ ├── Subscribe.java
│ │ └── UnSubscribe.java
│ │ ├── server
│ │ └── BrokerServer.java
│ │ ├── service
│ │ └── KafkaService.java
│ │ └── webapi
│ │ └── WebApiController.java
│ └── resources
│ ├── META-INF
│ └── nutz
│ │ └── org.nutz.boot.config.ConfigureLoader
│ ├── application.yaml
│ ├── banner.txt
│ ├── keystore
│ └── server.pfx
│ └── logback.xml
├── mqtt-client
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── cn
│ │ └── wizzer
│ │ └── iot
│ │ ├── ClientMainLauncher.java
│ │ ├── model
│ │ └── IotDev.java
│ │ └── mqtt
│ │ ├── MqttRecieveCallback.java
│ │ ├── MqttReciever.java
│ │ ├── MqttSender.java
│ │ └── MqttSenderCallback.java
│ └── resources
│ ├── application.properties
│ ├── banner.txt
│ └── logback.xml
├── mqtt-common
├── pom.xml
└── src
│ └── main
│ └── java
│ └── cn
│ └── wizzer
│ └── iot
│ └── mqtt
│ └── server
│ └── common
│ ├── auth
│ └── IAuthService.java
│ ├── message
│ ├── DupPubRelMessageStore.java
│ ├── DupPublishMessageStore.java
│ ├── IDupPubRelMessageStoreService.java
│ ├── IDupPublishMessageStoreService.java
│ ├── IMessageIdService.java
│ ├── IRetainMessageStoreService.java
│ └── RetainMessageStore.java
│ ├── session
│ ├── ISessionStoreService.java
│ └── SessionStore.java
│ └── subscribe
│ ├── ISubscribeStoreService.java
│ └── SubscribeStore.java
├── mqtt-store
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── cn
│ │ └── wizzer
│ │ └── iot
│ │ └── mqtt
│ │ └── server
│ │ └── store
│ │ ├── cache
│ │ ├── DupPubRelMessageCache.java
│ │ ├── DupPublishMessageCache.java
│ │ ├── RetainMessageCache.java
│ │ ├── SubscribeNotWildcardCache.java
│ │ └── SubscribeWildcardCache.java
│ │ ├── kafka
│ │ └── SimplePartitioner.java
│ │ ├── message
│ │ ├── DupPubRelMessageStoreService.java
│ │ ├── DupPublishMessageStoreService.java
│ │ ├── MessageIdService.java
│ │ └── RetainMessageStoreService.java
│ │ ├── session
│ │ └── SessionStoreService.java
│ │ ├── starter
│ │ └── StoreStarter.java
│ │ ├── subscribe
│ │ └── SubscribeStoreService.java
│ │ └── util
│ │ └── StoreUtil.java
│ └── resources
│ └── META-INF
│ └── nutz
│ └── org.nutz.boot.starter.NbStarter
├── mqtt-zoo
├── README.md
├── keystore
│ ├── server.cer
│ ├── server.crt
│ ├── server.jks
│ ├── server.key
│ └── server.pfx
├── linux_sysctl.txt
├── mqtt-test-kafka
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── cn
│ │ │ └── wizzer
│ │ │ └── iot
│ │ │ └── mqtt
│ │ │ └── server
│ │ │ └── test
│ │ │ ├── InternalMessage.java
│ │ │ └── KafkaLauncher.java
│ │ └── resources
│ │ ├── META-INF
│ │ └── nutz
│ │ │ └── org.nutz.boot.config.ConfigureLoader
│ │ ├── application.yaml
│ │ ├── banner.txt
│ │ └── logback.xml
├── mqtt-test-websocket
│ └── src
│ │ └── mqtt.html
└── test.png
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 | .project
4 | .vscode/
5 | .settings/
6 | .idea/
7 | .git/
8 | .DS_Store
9 |
10 | # Log file
11 | *.log
12 |
13 | # BlueJ files
14 | *.ctxt
15 |
16 | # Mobile Tools for Java (J2ME)
17 | .mtj.tmp/
18 |
19 | # Package Files #
20 | *.jar
21 | *.war
22 | *.nar
23 | *.ear
24 | *.zip
25 | *.tar.gz
26 | *.rar
27 |
28 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
29 | hs_err_pid*
30 |
31 | npm-debug.log*
32 | yarn-debug.log*
33 | yarn-error.log*
34 |
35 | # Runtime data
36 | pids
37 | *.pid
38 | *.seed
39 | *.pid.lock
40 |
41 | # Directory for instrumented libs generated by jscoverage/JSCover
42 | lib-cov
43 |
44 | # Coverage directory used by tools like istanbul
45 | coverage
46 |
47 | # nyc test coverage
48 | .nyc_output
49 |
50 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
51 | .grunt
52 |
53 | # Bower dependency directory (https://bower.io/)
54 | bower_components
55 |
56 | # node-waf configuration
57 | .lock-wscript
58 |
59 | # Compiled binary addons (https://nodejs.org/api/addons.html)
60 | build/Release
61 |
62 | # Dependency directories
63 | node_modules/
64 | jspm_packages/
65 |
66 | # TypeScript v1 declaration files
67 | typings/
68 |
69 | # Optional npm cache directory
70 | .npm
71 |
72 | # Optional eslint cache
73 | .eslintcache
74 |
75 | # Optional stylelint cache
76 | .stylelintcache
77 |
78 | # Optional REPL history
79 | .node_repl_history
80 |
81 | # Output of 'npm pack'
82 | *.tgz
83 |
84 | # Yarn Integrity file
85 | .yarn-integrity
86 |
87 | # dotenv environment variables file
88 | #.env
89 |
90 | # parcel-bundler cache (https://parceljs.org/)
91 | .cache
92 |
93 | # next.js build output
94 | .next
95 |
96 | # nuxt.js build output
97 | .nuxt
98 |
99 | # Nuxt generate
100 | dist
101 |
102 | # vuepress build output
103 | .vuepress/dist
104 |
105 | # Serverless directories
106 | .serverless
107 |
108 | # IDE
109 | .idea
110 |
111 | # Service worker
112 | sw.*
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
MqttWk - by netty
4 |
5 | [](https://github.com/Wizzercn/MqttWk/releases)
6 | [](https://www.apache.org/licenses/LICENSE-2.0.html)
7 | [](https://github.com/nutzam/nutzboot)
8 |
9 |
10 | 中文 | [English](README_EN.md)
11 |
12 | > 本项目开源免费,欢迎交流学习、贡献代码。
13 |
14 | #### MqttWk
15 | * QQ群号:225991747
16 |
17 | # 开发指南
18 |
19 | #### 技术体系
20 |
21 | 1. 使用 netty 实现通信及协议解析
22 | 2. 使用 nutzboot 提供依赖注入及属性配置
23 | 3. 使用 redis 实现消息缓存,集群
24 | 4. 使用 kafka 实现消息转发(可选)
25 |
26 | #### 项目结构
27 | ```
28 | MqttWk
29 | ├── mqtt-auth -- MQTT服务连接时用户名和密码认证
30 | ├── mqtt-broker -- MQTT服务器功能的核心实现
31 | ├── mqtt-common -- 公共类及其他模块使用的服务接口及对象
32 | ├── mqtt-store -- MQTT服务器会话信息(redis缓存及kafka加载)
33 | ├── mqtt-client -- MQTT客户端示例代码(配置文件修改数据库连接启动之)
34 | ├── mqtt-zoo -- 教程文档或文件
35 | ├── mqtt-test-kafka -- kafka消费者接收消息
36 | ├── mqtt-test-websocket -- websocket通信测试示例
37 | ```
38 |
39 | #### 功能说明
40 | 1. 参考MQTT3.1.1规范实现
41 | 2. 完整的QoS服务质量等级实现
42 | 3. 遗嘱消息, 保留消息及消息分发重试
43 | 4. 心跳机制
44 | 5. MQTT连接认证(可选择是否开启)
45 | 6. SSL方式连接(可选择是否开启)
46 | 7. 主题过滤(支持单主题订阅如 `test_topic` `/mqtt/test` --不能以/结尾, 通配符订阅 `#` `/mqtt/#` --以#结尾)
47 | 8. Websocket支持(可选择是否开启)
48 | 9. 集群功能(可选择是否开启)
49 | 10. Kafka消息转发功能(可选择是否开启)
50 | 11. 启动后查看统计数据 `http://127.0.0.1:8922/open/api/mqttwk/info`
51 |
52 | #### 快速开始
53 | - JDK1.8
54 | - 项目根目录执行 `mvn install`
55 | - mqtt-broker 下执行 `mvn clean package nutzboot:shade` 进行打包
56 | - 运行并加载jar内部yaml配置文件 `java -jar mqtt-broker-xxx.jar -Dnutz.profiles.active=prod` [此时加载application-prod.yaml配置文件]
57 | - 部署并加载指定文件夹下yaml配置文件 `nohup java -Dnutz.boot.configure.yaml.dir=/data -jar mqtt-broker-xxx.jar >/dev/null 2>&1 & `
58 | - 打开mqtt-spy客户端, 填写相应配置[下载](https://github.com/eclipse/paho.mqtt-spy/wiki/Downloads)
59 | - 连接端口: 8885, websocket 端口: 9995 websocket
60 | - 连接使用的用户名: demo
61 | - 连接使用的密码: 8F3B8DE2FDC8BD3D792BE77EAC412010971765E5BDD6C499ADCEE840CE441BDEF17E30684BD95CA708F55022222CC6161D0D23C2DFCB12F8AC998F59E7213393
62 | - 连接使用的证书在 `mqtt-zoo`\keystore\server.cer
63 |
64 | #### 集群使用
65 | - 多机环境集群:
66 |
67 | ```yaml
68 | mqttwk:
69 | broker:
70 | cluster-on: true
71 | kafka:
72 | # 是否启用kafka消息转发
73 | broker-enabled: false
74 | bootstrap:
75 | servers: 192.168.1.101:9092,192.168.1.102:9093
76 | redis:
77 | mode: cluster
78 | nodes: 192.168.1.103:16379,192.168.1.104:26379,192.168.1.103:36379
79 | ```
80 | - 单机环境集群:
81 |
82 | ```yaml
83 | mqttwk:
84 | broker:
85 | cluster-on: true
86 | kafka:
87 | # 是否启用kafka消息转发
88 | broker-enabled: false
89 | bootstrap:
90 | servers: 192.168.1.101:9092,192.168.1.102:9093
91 | redis:
92 | mode: normal
93 | host: 127.0.0.1
94 | port: 6379
95 | ```
96 |
97 | #### 自定义 - 连接认证
98 | - 默认只是简单使用对用户名进行RSA密钥对加密生成密码, 连接认证时对密码进行解密和相应用户名进行匹配认证
99 | - 使用中如果需要实现连接数据库或其他方式进行连接认证, 只需要重写`mqtt-auth`模块下的相应方法即可
100 |
101 | #### 自定义 - 服务端证书
102 | - 服务端证书存储在`mqtt-broker`的`resources/keystore/server.pfx`
103 | - 用户可以制作自己的证书, 但存储位置和文件名必须使用上述描述的位置及文件名
104 |
105 | #### 生产环境部署
106 | - 多机环境集群
107 | - 负载均衡: 富人用 L4 Switch,穷人用 Linux HAProxy
108 |
109 | #### 示例截图
110 | 
111 |
112 |
113 | # 参考项目
114 |
115 | * [https://github.com/netty/netty](https://github.com/netty/netty)
116 | * [https://gitee.com/recallcode/iot-mqtt-server](https://gitee.com/recallcode/iot-mqtt-server)
117 |
118 | > 如果您觉得还不错请在右上角点一下 star,帮忙转发,谢谢 ��🙏🙏 大家的支持是开源最大动力
119 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
MqttWk - powered by netty
4 |
5 | [](https://github.com/Wizzercn/MqttWk/releases)
6 | [](https://www.apache.org/licenses/LICENSE-2.0.html)
7 | [](https://github.com/nutzam/nutzboot)
8 |
9 |
10 | [中文](README.md) | English
11 |
12 | > This project is open source and free. Welcome to exchange, learn, and contribute code.
13 |
14 | #### MqttWk
15 | * QQ Group: 225991747
16 |
17 | # Development Guide
18 |
19 | #### Technology Stack
20 |
21 | 1. Using netty for communication and protocol parsing
22 | 2. Using nutzboot for dependency injection and property configuration
23 | 3. Using redis for message caching and clustering
24 | 4. Using kafka for message forwarding (optional)
25 |
26 | #### Project Structure
27 | ```
28 | MqttWk
29 | ├── mqtt-auth -- MQTT service username and password authentication
30 | ├── mqtt-broker -- Core implementation of MQTT server functionality
31 | ├── mqtt-common -- Common classes and service interfaces used by other modules
32 | ├── mqtt-store -- MQTT server session information (redis cache and kafka loading)
33 | ├── mqtt-client -- MQTT client example code (modify database connection in config file to start)
34 | ├── mqtt-zoo -- Tutorials, documents, or files
35 | ├── mqtt-test-kafka -- Kafka consumer for receiving messages
36 | ├── mqtt-test-websocket -- Websocket communication test example
37 | ```
38 |
39 | #### Features
40 | 1. Implemented according to MQTT 3.1.1 specification
41 | 2. Complete QoS service quality level implementation
42 | 3. Last will messages, retained messages, and message distribution retry
43 | 4. Heartbeat mechanism
44 | 5. MQTT connection authentication (optional)
45 | 6. SSL connection (optional)
46 | 7. Topic filtering (supports single topic subscription like `test_topic` or `/mqtt/test` --cannot end with /, wildcard subscription `#` or `/mqtt/#` --must end with #)
47 | 8. Websocket support (optional)
48 | 9. Clustering functionality (optional)
49 | 10. Kafka message forwarding (optional)
50 | 11. View statistics after startup at `http://127.0.0.1:8922/open/api/mqttwk/info`
51 |
52 | #### Quick Start
53 | - JDK 1.8
54 | - Execute `mvn install` in the project root directory
55 | - Execute `mvn clean package nutzboot:shade` in mqtt-broker for packaging
56 | - Run and load internal yaml configuration file: `java -jar mqtt-broker-xxx.jar -Dnutz.profiles.active=prod` [This loads the application-prod.yaml configuration file]
57 | - Deploy and load yaml configuration file from a specified folder: `nohup java -Dnutz.boot.configure.yaml.dir=/data -jar mqtt-broker-xxx.jar >/dev/null 2>&1 &`
58 | - Open mqtt-spy client and fill in the corresponding configuration [Download](https://github.com/eclipse/paho.mqtt-spy/wiki/Downloads)
59 | - Connection port: 8885, websocket port: 9995
60 | - Username for connection: demo
61 | - Password for connection: 8F3B8DE2FDC8BD3D792BE77EAC412010971765E5BDD6C499ADCEE840CE441BDEF17E30684BD95CA708F55022222CC6161D0D23C2DFCB12F8AC998F59E7213393
62 | - The certificate used for connection is in `mqtt-zoo`\keystore\server.cer
63 |
64 | #### Cluster Usage
65 | - Multi-machine environment cluster:
66 |
67 | ```yaml
68 | mqttwk:
69 | broker:
70 | cluster-on: true
71 | kafka:
72 | # Whether to enable kafka message forwarding
73 | broker-enabled: false
74 | bootstrap:
75 | servers: 192.168.1.101:9092,192.168.1.102:9093
76 | redis:
77 | mode: cluster
78 | nodes: 192.168.1.103:16379,192.168.1.104:26379,192.168.1.103:36379
79 | ```
80 | - Single machine environment cluster:
81 |
82 | ```yaml
83 | mqttwk:
84 | broker:
85 | cluster-on: true
86 | kafka:
87 | # Whether to enable kafka message forwarding
88 | broker-enabled: false
89 | bootstrap:
90 | servers: 192.168.1.101:9092,192.168.1.102:9093
91 | redis:
92 | mode: normal
93 | host: 127.0.0.1
94 | port: 6379
95 | ```
96 |
97 | #### Customization - Connection Authentication
98 | - By default, it simply uses RSA key pair encryption on the username to generate a password, and decrypts the password during connection authentication to match with the corresponding username
99 | - If you need to implement connection authentication using a database or other methods, you only need to override the corresponding methods in the `mqtt-auth` module
100 |
101 | #### Customization - Server Certificate
102 | - The server certificate is stored in `mqtt-broker`'s `resources/keystore/server.pfx`
103 | - Users can create their own certificates, but the storage location and filename must be as described above
104 |
105 | #### Production Environment Deployment
106 | - Multi-machine environment cluster
107 | - Load balancing: Rich people use L4 Switch, poor people use Linux HAProxy
108 |
109 | #### Example Screenshot
110 | 
111 |
112 |
113 | # Reference Projects
114 |
115 | * [https://github.com/netty/netty](https://github.com/netty/netty)
116 | * [https://gitee.com/recallcode/iot-mqtt-server](https://gitee.com/recallcode/iot-mqtt-server)
117 |
118 | > If you find this project helpful, please give it a star in the upper right corner and help spread the word. Thank you 🙏🙏🙏 Your support is the biggest motivation for open source
--------------------------------------------------------------------------------
/mqtt-auth/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | mqtt-wk
7 | cn.wizzer
8 | 1.4.0-netty
9 |
10 | 4.0.0
11 | jar
12 | mqtt-auth
13 |
14 |
15 | cn.wizzer
16 | mqtt-common
17 | ${mqttwk.version}
18 |
19 |
20 | org.nutz
21 | nutzboot-core
22 |
23 |
24 | cn.hutool
25 | hutool-crypto
26 | ${hutool.version}
27 |
28 |
29 |
--------------------------------------------------------------------------------
/mqtt-auth/src/main/java/cn/wizzer/iot/mqtt/server/auth/service/AuthService.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2018, Mr.Wang (recallcode@aliyun.com) All rights reserved.
3 | */
4 |
5 | package cn.wizzer.iot.mqtt.server.auth.service;
6 |
7 | import cn.hutool.core.io.IoUtil;
8 | import cn.hutool.core.util.StrUtil;
9 | import cn.hutool.crypto.asymmetric.KeyType;
10 | import cn.hutool.crypto.asymmetric.RSA;
11 | import cn.wizzer.iot.mqtt.server.common.auth.IAuthService;
12 | import org.nutz.ioc.loader.annotation.IocBean;
13 |
14 | import java.security.interfaces.RSAPrivateKey;
15 |
16 | /**
17 | * 用户名和密码认证服务
18 | */
19 | @IocBean(create = "init")
20 | public class AuthService implements IAuthService {
21 |
22 | private RSAPrivateKey privateKey;
23 |
24 | @Override
25 | public boolean checkValid(String username, String password) {
26 | if (StrUtil.isBlank(username)) return false;
27 | if (StrUtil.isBlank(password)) return false;
28 | RSA rsa = new RSA(privateKey, null);
29 | String value = rsa.encryptBcd(username, KeyType.PrivateKey);
30 | return value.equals(password) ? true : false;
31 | }
32 |
33 | public void init() {
34 | privateKey = IoUtil.readObj(AuthService.class.getClassLoader().getResourceAsStream("keystore/auth-private.key"));
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/mqtt-auth/src/main/java/cn/wizzer/iot/mqtt/server/auth/util/PwdUtil.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2018, Mr.Wang (recallcode@aliyun.com) All rights reserved.
3 | */
4 |
5 | package cn.wizzer.iot.mqtt.server.auth.util;
6 |
7 | import cn.hutool.core.io.IoUtil;
8 | import cn.hutool.crypto.asymmetric.KeyType;
9 | import cn.hutool.crypto.asymmetric.RSA;
10 |
11 | import java.io.IOException;
12 | import java.security.interfaces.RSAPrivateKey;
13 | import java.util.Scanner;
14 |
15 | /**
16 | * 密码
17 | */
18 | public class PwdUtil {
19 |
20 | /**
21 | * 通过用户名和私钥生成密码
22 | */
23 | public static void main(String[] args) throws IOException {
24 | System.out.println();
25 | System.out.print("输入需要获取密码的用户名: ");
26 | Scanner scanner = new Scanner(System.in);
27 | String value = scanner.nextLine();
28 | RSAPrivateKey privateKey = IoUtil.readObj(PwdUtil.class.getClassLoader().getResourceAsStream("keystore/auth-private.key"));
29 | RSA rsa = new RSA(privateKey, null);
30 | System.out.println("用户名: " + value + " 对应生成的密码为: " + rsa.encryptBcd(value, KeyType.PrivateKey));
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/mqtt-auth/src/main/java/cn/wizzer/iot/mqtt/server/auth/util/RsaKeyUtil.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2018, Mr.Wang (recallcode@aliyun.com) All rights reserved.
3 | */
4 |
5 | package cn.wizzer.iot.mqtt.server.auth.util;
6 |
7 | import cn.hutool.core.io.FileUtil;
8 | import cn.hutool.core.io.IoUtil;
9 | import cn.hutool.crypto.SecureUtil;
10 |
11 | import java.security.KeyPair;
12 | import java.security.interfaces.RSAPrivateKey;
13 | import java.time.LocalDateTime;
14 | import java.util.Scanner;
15 |
16 | /**
17 | * 私钥
18 | */
19 | public class RsaKeyUtil {
20 |
21 | /**
22 | * 生成私钥文件
23 | */
24 | public static void main(String[] args) {
25 | System.out.println();
26 | System.out.print("输入保存密钥文件的路径(如: D:/keystore/ ): ");
27 | Scanner scanner = new Scanner(System.in);
28 | String path = scanner.nextLine();
29 | KeyPair keyPair = SecureUtil.generateKeyPair("RSA", 512, LocalDateTime.now().toString().getBytes());
30 | RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
31 | String privatePath = path + "auth-private.key";
32 | IoUtil.writeObjects(FileUtil.getOutputStream(privatePath), true, privateKey);
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/mqtt-auth/src/main/resources/keystore/auth-private.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wizzercn/MqttWk/addfd0ad452a1917e8a95e3cf06096696ce3fc38/mqtt-auth/src/main/resources/keystore/auth-private.key
--------------------------------------------------------------------------------
/mqtt-broker/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | mqtt-wk
7 | cn.wizzer
8 | 1.4.0-netty
9 |
10 | 4.0.0
11 | jar
12 | mqtt-broker
13 |
14 |
15 | cn.wizzer
16 | mqtt-common
17 | ${mqttwk.version}
18 |
19 |
20 | cn.wizzer
21 | mqtt-store
22 | ${mqttwk.version}
23 |
24 |
25 | cn.wizzer
26 | mqtt-auth
27 | ${mqttwk.version}
28 |
29 |
30 | org.nutz
31 | nutzboot-core
32 |
33 |
34 | io.netty
35 | netty-codec-mqtt
36 | ${netty.version}
37 |
38 |
39 | io.netty
40 | netty-codec-http
41 | ${netty.version}
42 |
43 |
44 | io.netty
45 | netty-handler
46 | ${netty.version}
47 |
48 |
49 | io.netty
50 | netty-transport-native-epoll
51 | linux-x86_64
52 | ${netty.version}
53 |
54 |
55 | cn.hutool
56 | hutool-crypto
57 | ${hutool.version}
58 |
59 |
60 | org.nutz
61 | nutzboot-starter-nutz-mvc
62 | ${nutzboot.version}
63 |
64 |
65 | org.nutz
66 | nutzboot-starter-jetty
67 | ${nutzboot.version}
68 |
69 |
70 |
71 | org.slf4j
72 | slf4j-api
73 | ${slf4j.version}
74 |
75 |
76 | ch.qos.logback
77 | logback-core
78 | ${logback.version}
79 |
80 |
81 | ch.qos.logback
82 | logback-classic
83 | ${logback.version}
84 |
85 |
86 |
87 |
88 |
89 | org.nutz.boot
90 | nutzboot-maven-plugin
91 | ${nutzboot.version}
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/mqtt-broker/src/main/java/cn/wizzer/iot/mqtt/server/broker/MainLauncher.java:
--------------------------------------------------------------------------------
1 | package cn.wizzer.iot.mqtt.server.broker;
2 |
3 | import cn.wizzer.iot.mqtt.server.broker.server.BrokerServer;
4 | import org.nutz.boot.NbApp;
5 | import org.nutz.integration.jedis.RedisService;
6 | import org.nutz.ioc.Ioc;
7 | import org.nutz.ioc.impl.PropertiesProxy;
8 | import org.nutz.ioc.loader.annotation.Inject;
9 | import org.nutz.ioc.loader.annotation.IocBean;
10 | import org.nutz.log.Log;
11 | import org.nutz.log.Logs;
12 | import org.nutz.mvc.annotation.Modules;
13 |
14 | /**
15 | * Created by wizzer on 2018
16 | */
17 | @IocBean
18 | @Modules(packages = "cn.wizzer.iot")
19 | public class MainLauncher {
20 | private static final Log log = Logs.get();
21 | @Inject("refer:$ioc")
22 | private Ioc ioc;
23 | @Inject
24 | private PropertiesProxy conf;
25 | @Inject
26 | private RedisService redisService;
27 | @Inject
28 | private BrokerServer brokerServer;
29 |
30 | public static void main(String[] args) throws Exception {
31 | NbApp nb = new NbApp().setArgs(args).setPrintProcDoc(true);
32 | nb.setMainPackage("cn.wizzer.iot");
33 | nb.run();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/mqtt-broker/src/main/java/cn/wizzer/iot/mqtt/server/broker/cluster/RedisCluster.java:
--------------------------------------------------------------------------------
1 | package cn.wizzer.iot.mqtt.server.broker.cluster;
2 |
3 | import cn.wizzer.iot.mqtt.server.broker.config.BrokerProperties;
4 | import cn.wizzer.iot.mqtt.server.broker.internal.InternalMessage;
5 | import cn.wizzer.iot.mqtt.server.broker.internal.InternalSendServer;
6 | import com.alibaba.fastjson.JSONObject;
7 | import io.netty.handler.codec.mqtt.MqttQoS;
8 | import org.nutz.aop.interceptor.async.Async;
9 | import org.nutz.integration.jedis.pubsub.PubSub;
10 | import org.nutz.integration.jedis.pubsub.PubSubService;
11 | import org.nutz.ioc.loader.annotation.Inject;
12 | import org.nutz.ioc.loader.annotation.IocBean;
13 | import org.nutz.lang.Lang;
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 |
17 | /**
18 | * Created by wizzer on 2018
19 | */
20 | @IocBean(create = "init")
21 | public class RedisCluster implements PubSub {
22 | private static final Logger LOGGER = LoggerFactory.getLogger(RedisCluster.class);
23 | private static final String CLUSTER_TOPIC = "mqttwk:cluster";
24 | @Inject
25 | private PubSubService pubSubService;
26 | @Inject
27 | private BrokerProperties brokerProperties;
28 | @Inject
29 | private InternalSendServer internalSendServer;
30 |
31 | public void init() {
32 | pubSubService.reg(CLUSTER_TOPIC, this);
33 | }
34 |
35 | @Override
36 | public void onMessage(String channel, String message) {
37 | InternalMessage internalMessage = JSONObject.parseObject(message, InternalMessage.class);
38 | //判断进程ID是否是自身实例,若相同则不发送,否则集群模式下重复发消息
39 | if (!brokerProperties.getId().equals(internalMessage.getBrokerId()) && !Lang.JdkTool.getProcessId("0").equals(internalMessage.getProcessId()))
40 | internalSendServer.sendPublishMessage(internalMessage.getClientId(), internalMessage.getTopic(), MqttQoS.valueOf(internalMessage.getMqttQoS()), internalMessage.getMessageBytes(), internalMessage.isRetain(), internalMessage.isDup());
41 | }
42 |
43 | @Async
44 | public void sendMessage(InternalMessage internalMessage) {
45 | pubSubService.fire(CLUSTER_TOPIC, JSONObject.toJSONString(internalMessage));
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/mqtt-broker/src/main/java/cn/wizzer/iot/mqtt/server/broker/codec/MqttWebSocketCodec.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2018, Mr.Wang (recallcode@aliyun.com) All rights reserved.
3 | */
4 |
5 | package cn.wizzer.iot.mqtt.server.broker.codec;
6 |
7 | import io.netty.buffer.ByteBuf;
8 | import io.netty.channel.ChannelHandlerContext;
9 | import io.netty.handler.codec.MessageToMessageCodec;
10 | import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * WebSocket Mqtt消息编解码器
16 | */
17 | public class MqttWebSocketCodec extends MessageToMessageCodec {
18 |
19 | @Override
20 | protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List