├── mica-mqtt-common ├── README.md └── src │ ├── main │ ├── moditect │ │ └── module-info.java │ └── java │ │ └── org │ │ └── dromara │ │ └── mica │ │ └── mqtt │ │ └── core │ │ ├── serializer │ │ ├── MqttSerializer.java │ │ └── MqttJsonSerializer.java │ │ ├── annotation │ │ ├── MqttPayload.java │ │ ├── MqttRetain.java │ │ ├── MqttClientPublish.java │ │ └── MqttServerFunction.java │ │ ├── common │ │ ├── TopicTemplate.java │ │ └── TopicFilter.java │ │ ├── deserialize │ │ ├── MqttDeserializer.java │ │ └── MqttJsonDeserializer.java │ │ └── function │ │ ├── ParamValueFunction.java │ │ └── ObjectParamValueFunction.java │ └── test │ └── java │ └── org │ └── dromara │ └── mica │ └── mqtt │ └── core │ ├── util │ └── TestBean.java │ ├── timer │ └── SystemTimerTest.java │ ├── udp │ ├── UdpClusterTest1.java │ ├── UdpClusterTest2.java │ ├── UdpClusterConfig.java │ └── UdpTestHandler.java │ └── common │ └── TopicFilterTypeTest.java ├── example ├── mica-mqtt-example │ └── src │ │ ├── test │ │ ├── resources │ │ │ └── test.yml │ │ └── java │ │ │ └── net │ │ │ └── dreamlu │ │ │ └── iot │ │ │ └── package-info.java │ │ └── main │ │ ├── resources │ │ ├── ssl │ │ │ ├── README.md │ │ │ ├── dreamlu.net.jks │ │ │ ├── client-key.pem │ │ │ ├── ca-cert.pem │ │ │ └── client-cert.pem │ │ └── tinylog.properties │ │ └── java │ │ └── org │ │ └── dromara │ │ └── mica │ │ └── mqtt │ │ ├── benchmark │ │ └── MqttServerBench.java │ │ ├── nginx │ │ └── MqttServerProxyProtocol.java │ │ ├── broker │ │ ├── DeviceC.java │ │ ├── DeviceD.java │ │ ├── Server.java │ │ ├── DeviceB.java │ │ └── DeviceA.java │ │ ├── client │ │ ├── MqttClientConnTest.java │ │ └── MqttClientGlobalTest.java │ │ └── server │ │ └── MqttConnectStatusListener.java ├── mica-mqtt-client-spring-boot-example │ ├── README.md │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── dromara │ │ │ └── mica │ │ │ └── mqtt │ │ │ └── client │ │ │ ├── pojo │ │ │ └── User.java │ │ │ ├── MqttClientApplication.java │ │ │ ├── listener │ │ │ ├── OtherMqttClientSubscribeListener.java │ │ │ └── MqttClientMessageListener.java │ │ │ ├── controller │ │ │ └── ClientController.java │ │ │ ├── config │ │ │ └── OtherMqttClientConfiguration.java │ │ │ └── service │ │ │ ├── HelloInterfaceA.java │ │ │ ├── HelloInterfaceB.java │ │ │ └── ClientService.java │ │ └── resources │ │ └── banner.txt ├── mica-mqtt-client-solon-plugin-example │ ├── src │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── dromara │ │ │ │ └── mica │ │ │ │ └── mqtt │ │ │ │ └── client │ │ │ │ └── solon │ │ │ │ ├── pojo │ │ │ │ └── User.java │ │ │ │ ├── MqttClientApplication.java │ │ │ │ ├── controller │ │ │ │ └── ClientController.java │ │ │ │ ├── service │ │ │ │ └── ClientService.java │ │ │ │ └── listener │ │ │ │ ├── MqttClientMessageListener.java │ │ │ │ ├── MqttClientConnectedListener.java │ │ │ │ └── MqttClientDisconnectListener.java │ │ │ └── resources │ │ │ └── app.yml │ └── pom.xml ├── mica-mqtt-server-spring-boot-example │ ├── README.md │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── dromara │ │ │ └── mica │ │ │ └── mqtt │ │ │ └── server │ │ │ ├── test │ │ │ └── JsonUtilTest.java │ │ │ ├── pojo │ │ │ └── User.java │ │ │ ├── MqttServerApplication.java │ │ │ ├── auth │ │ │ ├── MqttAuthHandler.java │ │ │ ├── MqttUniqueIdService.java │ │ │ ├── MqttSubscribeValidator.java │ │ │ └── MqttHttpAuthFilter.java │ │ │ ├── service │ │ │ └── ServerService.java │ │ │ ├── task │ │ │ └── PublishAllTask.java │ │ │ ├── controller │ │ │ └── ServerController.java │ │ │ └── listener │ │ │ ├── MqttConnectStatusListener1.java │ │ │ ├── MqttServerMessageListener1.java │ │ │ └── MqttConnectStatusListener2.java │ │ └── resources │ │ └── banner.txt └── mica-mqtt-server-solon-plugin-example │ └── src │ └── main │ └── java │ └── org │ └── dromara │ └── mica │ └── mqtt │ └── server │ └── solon │ ├── pojo │ └── User.java │ ├── MqttServerApplication.java │ ├── controller │ └── ServerController.java │ ├── service │ └── ServerService.java │ ├── task │ └── PublishTask.java │ └── listener │ ├── MqttServerMessageListener1.java │ ├── MqttConnectOnlineListener.java │ └── MqttConnectOfflineListener.java ├── docs ├── graalvm.md ├── img │ ├── mica-mqtt.jpg │ └── dreamlu-weixin.jpg └── http │ └── http-client.env.json ├── .idea └── icon.png ├── .codacy.yml ├── mica-mqtt-client ├── src │ └── main │ │ ├── moditect │ │ └── module-info.java │ │ └── java │ │ └── org │ │ └── dromara │ │ └── mica │ │ └── mqtt │ │ └── core │ │ └── client │ │ ├── MqttClientId.java │ │ ├── MqttClientCustomizer.java │ │ ├── IMqttClientGlobalMessageListener.java │ │ ├── IMqttClient.java │ │ └── IMqttClientConnectListener.java └── pom.xml ├── starter ├── mica-mqtt-client-solon-plugin │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ └── META-INF │ │ │ │ │ └── solon │ │ │ │ │ └── solon.mica.client.properties │ │ │ ├── moditect │ │ │ │ └── module-info.java │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── dromara │ │ │ │ └── mica │ │ │ │ └── mqtt │ │ │ │ └── client │ │ │ │ └── solon │ │ │ │ └── event │ │ │ │ ├── MqttConnectedEvent.java │ │ │ │ └── MqttDisconnectEvent.java │ │ └── test │ │ │ ├── java │ │ │ └── org │ │ │ │ └── dromara │ │ │ │ └── mica │ │ │ │ └── mqtt │ │ │ │ └── client │ │ │ │ └── solon │ │ │ │ └── test │ │ │ │ ├── ClientTest.java │ │ │ │ └── listener │ │ │ │ ├── MqttClientMessageListener.java │ │ │ │ ├── MqttClientSubscribeListener.java │ │ │ │ └── MqttClientConnectListener.java │ │ │ └── resources │ │ │ └── app.yml │ └── pom.xml ├── mica-mqtt-server-solon-plugin │ └── src │ │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── solon │ │ │ │ └── solon.mica.server.properties │ │ ├── moditect │ │ │ └── module-info.java │ │ └── java │ │ │ └── org │ │ │ └── dromara │ │ │ └── mica │ │ │ └── mqtt │ │ │ └── server │ │ │ └── solon │ │ │ └── event │ │ │ ├── MqttClientOfflineEvent.java │ │ │ └── MqttClientOnlineEvent.java │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── dromara │ │ │ └── mica │ │ │ └── mqtt │ │ │ └── server │ │ │ └── solon │ │ │ └── test │ │ │ └── task │ │ │ ├── ServerTest.java │ │ │ └── task │ │ │ └── PublishAllTask.java │ │ └── resources │ │ └── app.yml ├── mica-mqtt-client-jfinal-plugin │ ├── src │ │ ├── main │ │ │ └── moditect │ │ │ │ └── module-info.java │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── dromara │ │ │ └── mica │ │ │ └── mqtt │ │ │ └── jfinal │ │ │ └── client │ │ │ └── MqttClientPluginTest.java │ └── pom.xml ├── mica-mqtt-server-jfinal-plugin │ ├── src │ │ ├── main │ │ │ └── moditect │ │ │ │ └── module-info.java │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── dromara │ │ │ └── mica │ │ │ └── mqtt │ │ │ └── jfinal │ │ │ └── server │ │ │ └── MqttServerPluginTest.java │ ├── README.md │ └── pom.xml ├── mica-mqtt-server-spring-boot-starter │ └── src │ │ └── main │ │ ├── moditect │ │ └── module-info.java │ │ └── java │ │ └── org │ │ └── dromara │ │ └── mica │ │ └── mqtt │ │ └── spring │ │ └── server │ │ ├── event │ │ ├── MqttClientOfflineEvent.java │ │ └── MqttClientOnlineEvent.java │ │ └── config │ │ └── MqttServerMetricsConfiguration.java ├── mica-mqtt-client-spring-boot-starter │ ├── src │ │ └── main │ │ │ ├── moditect │ │ │ └── module-info.java │ │ │ └── java │ │ │ └── org │ │ │ └── dromara │ │ │ └── mica │ │ │ └── mqtt │ │ │ └── spring │ │ │ └── client │ │ │ ├── event │ │ │ ├── MqttConnectedEvent.java │ │ │ └── MqttDisconnectEvent.java │ │ │ └── annotation │ │ │ ├── EnableMqttClients.java │ │ │ └── MqttClient.java │ └── pom.xml ├── README.md └── pom.xml ├── mica-mqtt-server └── src │ ├── test │ ├── resources │ │ └── tinylog.properties │ └── java │ │ └── org │ │ └── dromara │ │ └── mica │ │ └── mqtt │ │ └── core │ │ └── server │ │ └── test │ │ └── cluster │ │ ├── ClusterTest2.java │ │ ├── ClusterTest3.java │ │ ├── ClusterTest4.java │ │ └── ClusterTest1.java │ └── main │ ├── java │ └── org │ │ └── dromara │ │ └── mica │ │ └── mqtt │ │ └── core │ │ └── server │ │ ├── MqttConst.java │ │ ├── MqttServerCustomizer.java │ │ ├── http │ │ ├── api │ │ │ └── form │ │ │ │ ├── SubscribeForm.java │ │ │ │ ├── BaseForm.java │ │ │ │ └── PublishForm.java │ │ └── handler │ │ │ └── HttpFilter.java │ │ ├── session │ │ └── SharedStrategy.java │ │ ├── broker │ │ └── DefaultMqttBrokerDispatcher.java │ │ ├── serializer │ │ ├── IMessageSerializer.java │ │ └── JsonMessageSerializer.java │ │ ├── support │ │ ├── DefaultMqttServerUniqueIdServiceImpl.java │ │ ├── DefaultMqttConnectStatusListener.java │ │ └── DefaultMqttServerAuthHandler.java │ │ ├── auth │ │ └── IMqttServerUniqueIdService.java │ │ ├── protocol │ │ └── MqttProtocol.java │ │ ├── event │ │ ├── IMqttMessageListener.java │ │ ├── IMqttConnectStatusListener.java │ │ └── IMqttSessionListener.java │ │ ├── dispatcher │ │ └── IMqttMessageDispatcher.java │ │ └── func │ │ └── IMqttFunctionMessageListener.java │ └── moditect │ └── module-info.java ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── issue.yml ├── pull_request_template.md ├── renovate.json ├── workflows │ ├── test-and-build.yml │ └── publish-snapshot.yml └── dependabot.yml ├── .gitee └── ISSUE_TEMPLATE │ ├── config.yml │ └── issue.yml ├── .editorconfig ├── SECURITY.md ├── .gitattributes ├── mica-mqtt-codec ├── src │ ├── main │ │ ├── moditect │ │ │ └── module-info.java │ │ └── java │ │ │ └── org │ │ │ └── dromara │ │ │ └── mica │ │ │ └── mqtt │ │ │ └── codec │ │ │ ├── properties │ │ │ ├── UserProperty.java │ │ │ ├── StringProperty.java │ │ │ ├── IntegerProperty.java │ │ │ ├── BinaryProperty.java │ │ │ ├── BooleanProperty.java │ │ │ └── StringPair.java │ │ │ ├── codes │ │ │ ├── MqttAuthReasonCode.java │ │ │ ├── MqttReasonCode.java │ │ │ ├── MqttUnSubAckReasonCode.java │ │ │ ├── MqttPubRelReasonCode.java │ │ │ ├── MqttPubCompReasonCode.java │ │ │ └── ReasonCodeUtils.java │ │ │ ├── exception │ │ │ ├── DecoderException.java │ │ │ └── EncoderException.java │ │ │ ├── MqttConstant.java │ │ │ └── message │ │ │ ├── payload │ │ │ └── MqttUnsubscribePayload.java │ │ │ ├── MqttConnAckMessage.java │ │ │ └── MqttPubAckMessage.java │ └── test │ │ └── java │ │ └── org │ │ └── dromara │ │ └── mica │ │ └── mqtt │ │ └── codec │ │ └── test │ │ └── MqttCodecUtilTest.java └── pom.xml ├── .gitignore └── deploy.sh /mica-mqtt-common/README.md: -------------------------------------------------------------------------------- 1 | # 公用的工具类 2 | 3 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/test/resources/test.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/graalvm.md: -------------------------------------------------------------------------------- 1 | # mica-mqtt 之 GraalVM native-image 编译成本机可执行程序 2 | 3 | -------------------------------------------------------------------------------- /.idea/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dromara/mica-mqtt/HEAD/.idea/icon.png -------------------------------------------------------------------------------- /docs/img/mica-mqtt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dromara/mica-mqtt/HEAD/docs/img/mica-mqtt.jpg -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/test/java/net/dreamlu/iot/package-info.java: -------------------------------------------------------------------------------- 1 | package net.dreamlu.iot; 2 | -------------------------------------------------------------------------------- /docs/img/dreamlu-weixin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dromara/mica-mqtt/HEAD/docs/img/dreamlu-weixin.jpg -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/resources/ssl/README.md: -------------------------------------------------------------------------------- 1 | ssl 自签双向证书详见:https://gitee.com/596392912/mica-mqtt/issues/I45GO7 -------------------------------------------------------------------------------- /.codacy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | exclude_paths: 3 | - '.mvn/**' 4 | - '**.md' 5 | - '**/**.md' 6 | - 'mica-mqtt-example/**' 7 | - '**/test/**' 8 | -------------------------------------------------------------------------------- /docs/http/http-client.env.json: -------------------------------------------------------------------------------- 1 | { 2 | "local": { 3 | "host": "127.0.0.1:18083", 4 | "username": "mica", 5 | "password": "mica" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/resources/ssl/dreamlu.net.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dromara/mica-mqtt/HEAD/example/mica-mqtt-example/src/main/resources/ssl/dreamlu.net.jks -------------------------------------------------------------------------------- /mica-mqtt-client/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.client { 2 | requires transitive org.dromara.mica.mqtt.common; 3 | exports org.dromara.mica.mqtt.core.client; 4 | } 5 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/src/main/resources/META-INF/solon/solon.mica.client.properties: -------------------------------------------------------------------------------- 1 | solon.plugin=org.dromara.mica.mqtt.client.solon.integration.MqttClientPluginImpl 2 | solon.plugin.priority=1 3 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-solon-plugin/src/main/resources/META-INF/solon/solon.mica.server.properties: -------------------------------------------------------------------------------- 1 | solon.plugin=org.dromara.mica.mqtt.server.solon.integration.MqttServerPluginImpl 2 | solon.plugin.priority=1 3 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/README.md: -------------------------------------------------------------------------------- 1 | ## SpringBoot + mica-mqtt-client 应用演示 2 | 3 | ## 启动步骤 4 | 1. 先启动 mica-mqtt-server-spring-boot-example 5 | 6 | 2. 再启动 mica-mqtt-client-spring-boot-example 7 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-jfinal-plugin/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.client.jfinal.plugin { 2 | requires jfinal; 3 | requires transitive org.dromara.mica.mqtt.client; 4 | exports org.dromara.mica.mqtt.jfinal.client; 5 | } 6 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-jfinal-plugin/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.server.jfinal.plugin { 2 | requires jfinal; 3 | requires transitive org.dromara.mica.mqtt.server; 4 | exports org.dromara.mica.mqtt.jfinal.server; 5 | } 6 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/java/org/dromara/mica/mqtt/client/pojo/User.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.pojo; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class User { 7 | private String name; 8 | private T girlfriend; 9 | } 10 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/client/solon/pojo/User.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.solon.pojo; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class User { 7 | private String name; 8 | private T girlfriend; 9 | } 10 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/test/resources/tinylog.properties: -------------------------------------------------------------------------------- 1 | writer = console 2 | writer.format = {date: HH:mm:ss.SSS} [{thread}] {level} {class-name}.{method} : {message} 3 | writer.level = info 4 | # level 5 | level@org.tio = info 6 | level@org.tio.client.TioClient = info 7 | level@org.tio.server = info 8 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/resources/tinylog.properties: -------------------------------------------------------------------------------- 1 | writer = console 2 | writer.format = {date: HH:mm:ss.SSS} [{thread}] {level} {class-name}.{method} : {message} 3 | writer.level = info 4 | # level 5 | level@org.tio = warn 6 | level@org.tio.client.TioClient = off 7 | level@org.tio.server = info 8 | level@org.dromara.mica.mqtt = info 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 遇到问题请先看《使用中常见问题汇总》!谢谢!!! 4 | url: https://gitee.com/596392912/mica-mqtt/issues/I45GO7 5 | about: 该文档可以解决你90%的疑惑 6 | - name: 老版本用户建议升级到新版,详见《发行版本》!谢谢!!! 7 | url: https://gitee.com/596392912/mica-mqtt/blob/master/CHANGELOG.md 8 | about: 完整的《发行版本》记录 9 | -------------------------------------------------------------------------------- /.gitee/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false # 不允许用户创建空白 Issue 2 | contact_links: 3 | - name: 遇到问题请先看《使用中常见问题汇总》!谢谢!!! 4 | url: https://gitee.com/596392912/mica-mqtt/issues/I45GO7 5 | about: 该文档可以解决你90%的疑惑 6 | - name: 老版本用户建议升级到新版,详见《发行版本》!谢谢!!! 7 | url: https://gitee.com/596392912/mica-mqtt/blob/master/CHANGELOG.md 8 | about: 完整的《发行版本》记录 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | # 空格替代Tab缩进在各种编辑工具下效果一致 5 | [*] 6 | indent_style = space 7 | indent_size = 4 8 | charset = utf-8 9 | end_of_line = lf 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | 13 | [*.java] 14 | indent_style = tab 15 | 16 | [*.{json,yml}] 17 | indent_size = 2 18 | 19 | [*.md] 20 | insert_final_newline = false 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy(安全策略) 2 | 3 | ## Supported Versions(支持的版本) 4 | 5 | | Version | Supported | 6 | |---------|--------------------| 7 | | 2.4.x | :white_check_mark: | 8 | | < 2.4.x | :x: | 9 | 10 | ## Reporting a Vulnerability(报告漏洞) 11 | 12 | 如果你发现有安全问题或漏洞,请发送邮件到 `596392912@qq.com`。 13 | 14 | To report any found security issues or vulnerabilities, please send a mail to `596392912@qq.com`. 15 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | **注意:github 上的少,可能响应不够及时,建议 gitee 上发起** 2 | 3 | **What kind of change does this PR introduce?** (check at least one) 4 | 5 | - [ ] Bugfix(bug修复) 6 | - [ ] Feature(新功能) 7 | - [ ] Code style update(代码格式调整) 8 | - [ ] Refactor(重构) 9 | - [ ] Build-related changes(与构建相关的更改) 10 | - [ ] Other, please describe(其他,请说明): 11 | 12 | **The description of the PR(PR描述):** 13 | 14 | 15 | **Other information(其他信息):** 16 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/README.md: -------------------------------------------------------------------------------- 1 | ## SpringBoot + mica-mqtt-server 应用演示 2 | 3 | ## 启动步骤 4 | 1. 先启动 mica-mqtt-server-spring-boot-example 5 | 6 | 2. 再启动 mica-mqtt-client-spring-boot-example 7 | 8 | 3. 查看控制器 swagger 地址:http://localhost:30012/doc.html 9 | 10 | 4. 可开启 prometheus 指标收集,详见: http://localhost:30012/actuator/prometheus 11 | 12 | ## 连接 13 | 14 | mica Spring boot 开发组件集文档:https://www.dreamlu.net/components/mica-swagger.html 15 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/test/JsonUtilTest.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.test; 2 | 3 | import org.tio.utils.json.JsonUtil; 4 | 5 | public class JsonUtilTest { 6 | 7 | public static void main(String[] args) { 8 | String json = "{\"a\":\"1\",\"b\":\"2\"}"; 9 | System.out.println(JsonUtil.isValidJson(json)); 10 | Object value = JsonUtil.readValue(json, Object.class); 11 | System.out.println(value); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.client.solon.plugin { 2 | requires solon; 3 | requires lombok; 4 | requires transitive org.dromara.mica.mqtt.client; 5 | exports org.dromara.mica.mqtt.client.solon; 6 | exports org.dromara.mica.mqtt.client.solon.event; 7 | exports org.dromara.mica.mqtt.client.solon.config; 8 | provides org.noear.solon.core.Plugin with org.dromara.mica.mqtt.client.solon.integration.MqttClientPluginImpl; 9 | } 10 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-solon-plugin/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.server.solon.plugin { 2 | requires solon; 3 | requires lombok; 4 | requires transitive org.dromara.mica.mqtt.server; 5 | exports org.dromara.mica.mqtt.server.noear; 6 | exports org.dromara.mica.mqtt.server.solon.event; 7 | exports org.dromara.mica.mqtt.server.solon.config; 8 | provides org.noear.solon.core.Plugin with org.dromara.mica.mqtt.server.solon.integration.MqttServerPluginImpl; 9 | } 10 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-spring-boot-starter/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.server.spring.boot.starter { 2 | requires lombok; 3 | requires spring.core; 4 | requires spring.context; 5 | requires spring.boot; 6 | requires spring.boot.autoconfigure; 7 | requires transitive org.dromara.mica.mqtt.server; 8 | exports org.dromara.mica.mqtt.spring.server; 9 | exports org.dromara.mica.mqtt.spring.server.config; 10 | exports org.dromara.mica.mqtt.spring.server.event; 11 | } 12 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/pojo/User.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.pojo; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class User { 7 | private String name; 8 | private T girlfriend; 9 | 10 | public static User newUser(){ 11 | User user1 = new User(); 12 | user1.setName("name1"); 13 | 14 | User user2 = new User(); 15 | user2.setName("name2"); 16 | user2.setGirlfriend(user1); 17 | return user2; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/server/solon/pojo/User.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.solon.pojo; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class User { 7 | private String name; 8 | private T girlfriend; 9 | 10 | public static User newUser(){ 11 | User user1 = new User(); 12 | user1.setName("name1"); 13 | 14 | User user2 = new User(); 15 | user2.setName("name2"); 16 | user2.setGirlfriend(user1); 17 | return user2; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ], 6 | "baseBranches": [ 7 | "dev" 8 | ], 9 | "packageRules": [ 10 | { 11 | "matchPackagePatterns": [ 12 | "^net.dreamlu:mica-bom$", 13 | "^net.dreamlu:mica-auto$", 14 | "^org.springframework.boot:spring-boot-dependencies$", 15 | "^org.springframework.boot:spring-boot-maven-plugin$" 16 | ], 17 | "enabled": false 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /mica-mqtt-client/src/main/java/org/dromara/mica/mqtt/core/client/MqttClientId.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.client; 2 | 3 | import org.tio.core.intf.TioUuid; 4 | 5 | /** 6 | * 将 mqtt clientId 绑定到 context 中 7 | * 8 | * @author L.cm 9 | */ 10 | public class MqttClientId implements TioUuid { 11 | private final MqttClientCreator creator; 12 | 13 | public MqttClientId(MqttClientCreator creator) { 14 | this.creator = creator; 15 | } 16 | 17 | @Override 18 | public String uuid() { 19 | return creator.getClientId(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.common { 2 | requires transitive net.dreamlu.mica.net.core; 3 | requires transitive org.dromara.mica.mqtt.codec; 4 | exports org.dromara.mica.mqtt.core.annotation; 5 | exports org.dromara.mica.mqtt.core.common; 6 | exports org.dromara.mica.mqtt.core.deserialize; 7 | exports org.dromara.mica.mqtt.core.function; 8 | exports org.dromara.mica.mqtt.core.serializer; 9 | exports org.dromara.mica.mqtt.core.util; 10 | exports org.dromara.mica.mqtt.core.util.timer; 11 | } 12 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/client/solon/MqttClientApplication.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.solon; 2 | 3 | import org.noear.solon.Solon; 4 | import org.noear.solon.annotation.Configuration; 5 | 6 | /** 7 | * @author wsq 8 | */ 9 | @Configuration 10 | public class MqttClientApplication { 11 | 12 | /** 13 | * 先启动 mica-mqtt-server-spring-boot-example 再启动本项目,进行测试 14 | */ 15 | public static void main(String[] args) { 16 | Solon.start(MqttClientApplication.class, args); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-solon-plugin/src/test/java/org/dromara/mica/mqtt/server/solon/test/task/ServerTest.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.solon.test.task; 2 | 3 | import org.noear.solon.Solon; 4 | import org.noear.solon.scheduling.annotation.EnableScheduling; 5 | 6 | /** 7 | * (ServerTest) 8 | * 9 | * @author Peigen 10 | * @version 1.0.0 11 | * @since 2023/7/15 12 | */ 13 | @EnableScheduling 14 | public class ServerTest { 15 | 16 | public static void main(String[] args) { 17 | Solon.start(ServerTest.class,args); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-spring-boot-starter/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.client.spring.boot.starter { 2 | requires lombok; 3 | requires spring.core; 4 | requires spring.context; 5 | requires spring.boot; 6 | requires spring.boot.autoconfigure; 7 | requires transitive org.dromara.mica.mqtt.client; 8 | exports org.dromara.mica.mqtt.spring.client; 9 | exports org.dromara.mica.mqtt.spring.client.annotation; 10 | exports org.dromara.mica.mqtt.spring.client.config; 11 | exports org.dromara.mica.mqtt.spring.client.event; 12 | } 13 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/server/solon/MqttServerApplication.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.solon; 2 | 3 | 4 | import org.noear.solon.Solon; 5 | import org.noear.solon.annotation.Configuration; 6 | import org.noear.solon.scheduling.annotation.EnableScheduling; 7 | 8 | /** 9 | * @author wsq 10 | */ 11 | @Configuration 12 | @EnableScheduling 13 | public class MqttServerApplication { 14 | 15 | public static void main(String[] args) { 16 | Solon.start(MqttServerApplication.class, args); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # All text files should have the "lf" (Unix) line endings 2 | * text eol=lf 3 | # windows cmd shoud have the "crlf" (Win32) line endings 4 | *.cmd eol=crlf 5 | 6 | # Explicitly declare text files you want to always be normalized and converted 7 | # to native line endings on checkout. 8 | *.java text 9 | *.js text 10 | *.css text 11 | *.html text 12 | *.properties text 13 | *.xml text 14 | *.yml text 15 | 16 | # Denote all files that are truly binary and should not be modified. 17 | *.png binary 18 | *.jpg binary 19 | *.ttf binary 20 | *.jar binary 21 | *.db binary 22 | *.xdb binary 23 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-jfinal-plugin/src/test/java/org/dromara/mica/mqtt/jfinal/client/MqttClientPluginTest.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.jfinal.client; 2 | 3 | /** 4 | * mica mqtt client 插件测试 5 | * 6 | * @author L.cm 7 | */ 8 | public class MqttClientPluginTest { 9 | 10 | public static void main(String[] args) { 11 | MqttClientPlugin plugin = new MqttClientPlugin(); 12 | plugin.config(mqttClientCreator -> { 13 | // mqttClientCreator 上有很多方法,详见 mica-mqtt-core 14 | mqttClientCreator.port(1883).username("mica").password("mica"); 15 | }); 16 | plugin.start(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.codec { 2 | requires net.dreamlu.mica.net.core; 3 | exports org.dromara.mica.mqtt.codec; 4 | exports org.dromara.mica.mqtt.codec.codes; 5 | exports org.dromara.mica.mqtt.codec.exception; 6 | exports org.dromara.mica.mqtt.codec.message; 7 | exports org.dromara.mica.mqtt.codec.message.builder; 8 | exports org.dromara.mica.mqtt.codec.message.header; 9 | exports org.dromara.mica.mqtt.codec.message.payload; 10 | exports org.dromara.mica.mqtt.codec.message.properties; 11 | exports org.dromara.mica.mqtt.codec.properties; 12 | } 13 | -------------------------------------------------------------------------------- /starter/README.md: -------------------------------------------------------------------------------- 1 | # 插件 2 | 3 | ## Spring boot 4 | 5 | - [mica-mqtt-client-spring-boot-starter 使用文档](mica-mqtt-client-spring-boot-starter/README.md) 6 | - [mica-mqtt-server-spring-boot-starter 使用文档](mica-mqtt-server-spring-boot-starter/README.md) 7 | 8 | ## solon 9 | 10 | - [mica-mqtt-client-solon-plugin 使用文档](mica-mqtt-client-solon-plugin/README.md) 11 | - [mica-mqtt-server-solon-plugin 使用文档](mica-mqtt-server-solon-plugin/README.md) 12 | 13 | ## JFinal 14 | 15 | - [mica-mqtt-client-jfinal-plugin 使用文档](mica-mqtt-client-jfinal-plugin/README.md) 16 | - [mica-mqtt-server-jfinal-plugin 使用文档](mica-mqtt-server-jfinal-plugin/README.md) 17 | -------------------------------------------------------------------------------- /.github/workflows/test-and-build.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | permissions: 3 | contents: read 4 | on: [push, pull_request] 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | strategy: 10 | matrix: 11 | java: [ '8', '21' ] 12 | name: Java ${{ matrix.Java }} build 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-java@v4 16 | with: 17 | distribution: 'zulu' 18 | java-version: ${{ matrix.java }} 19 | cache: 'maven' 20 | cache-dependency-path: 'pom.xml' 21 | - name: Build with Maven 22 | run: mvn package -P !develop 23 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-jfinal-plugin/src/test/java/org/dromara/mica/mqtt/jfinal/server/MqttServerPluginTest.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.jfinal.server; 2 | 3 | /** 4 | * mica mqtt server 插件测试 5 | * 6 | * @author L.cm 7 | */ 8 | public class MqttServerPluginTest { 9 | 10 | public static void main(String[] args) { 11 | MqttServerPlugin plugin = new MqttServerPlugin(); 12 | plugin.config(mqttServerCreator -> { 13 | // mqttServerCreator 上有很多方法,详见 mica-mqtt-core 14 | mqttServerCreator 15 | .enableMqtt() 16 | .enableMqttWs() 17 | .enableMqttHttpApi() 18 | ; 19 | }); 20 | plugin.start(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/client/solon/controller/ClientController.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.solon.controller; 2 | 3 | 4 | import org.dromara.mica.mqtt.client.solon.service.ClientService; 5 | import org.noear.solon.annotation.*; 6 | 7 | @Mapping("/mqtt/client") 8 | @Controller 9 | public class ClientController { 10 | 11 | @Inject 12 | private ClientService service; 13 | 14 | @Post 15 | @Mapping("/publish") 16 | public boolean publish(String body) { 17 | return service.publish(body); 18 | } 19 | 20 | @Get 21 | @Mapping("/sub") 22 | public boolean sub() { 23 | return service.sub(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/MqttServerApplication.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | /** 8 | * @author wsq 9 | */ 10 | @SpringBootApplication 11 | @EnableScheduling 12 | public class MqttServerApplication { 13 | 14 | /** 15 | * 先启动本项目,再启动 mica-mqtt-client-spring-boot-example 进行测试 16 | */ 17 | public static void main(String[] args) { 18 | SpringApplication.run(MqttServerApplication.class, args); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/java/org/dromara/mica/mqtt/client/MqttClientApplication.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client; 2 | 3 | import org.dromara.mica.mqtt.spring.client.annotation.EnableMqttClients; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | /** 8 | * @author wsq 9 | */ 10 | @SpringBootApplication 11 | @EnableMqttClients 12 | public class MqttClientApplication { 13 | 14 | /** 15 | * 先启动 mica-mqtt-server-spring-boot-example 再启动本项目,进行测试 16 | */ 17 | public static void main(String[] args) { 18 | SpringApplication.run(MqttClientApplication.class, args); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/server/solon/controller/ServerController.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.solon.controller; 2 | 3 | 4 | import org.dromara.mica.mqtt.server.solon.service.ServerService; 5 | import org.noear.solon.annotation.Controller; 6 | import org.noear.solon.annotation.Inject; 7 | import org.noear.solon.annotation.Mapping; 8 | import org.noear.solon.annotation.Post; 9 | 10 | @Mapping("/mqtt/server") 11 | @Controller 12 | public class ServerController { 13 | @Inject 14 | private ServerService service; 15 | 16 | @Mapping("publish") 17 | @Post 18 | public boolean publish(String body) { 19 | return service.publish(body); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/auth/MqttAuthHandler.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.auth; 2 | 3 | import org.dromara.mica.mqtt.core.server.auth.IMqttServerAuthHandler; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.tio.core.ChannelContext; 6 | 7 | /** 8 | * 示例 mqtt tcp、websocket 认证,请按照自己的需求和业务进行扩展 9 | * 10 | * @author L.cm 11 | */ 12 | @Configuration(proxyBeanMethods = false) 13 | public class MqttAuthHandler implements IMqttServerAuthHandler { 14 | 15 | @Override 16 | public boolean authenticate(ChannelContext context, String uniqueId, String clientId, String username, String password) { 17 | // 客户端认证逻辑实现 18 | return true; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "maven" 9 | target-branch: "dev" # 更新到 dev 分支 10 | directory: "/" 11 | schedule: 12 | interval: "daily" 13 | commit-message: 14 | prefix: ":arrow_up:" # 提交信息前缀 15 | ignore: 16 | - dependency-name: "io.undertow.*" 17 | - dependency-name: "org.springframework.*" 18 | - dependency-name: "net.dreamlu:mica-bom" 19 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/auth/MqttUniqueIdService.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.auth; 2 | 3 | import org.dromara.mica.mqtt.core.server.auth.IMqttServerUniqueIdService; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.tio.core.ChannelContext; 6 | 7 | /** 8 | * 示例自定义 clientId,请按照自己的需求和业务进行扩展 9 | * 10 | * @author L.cm 11 | */ 12 | @Configuration(proxyBeanMethods = false) 13 | public class MqttUniqueIdService implements IMqttServerUniqueIdService { 14 | 15 | @Override 16 | public String getUniqueId(ChannelContext context, String clientId, String userName, String password) { 17 | // 返回的 uniqueId 会替代 mqtt client 传过来的 clientId,请保证返回的 uniqueId 唯一。 18 | return clientId; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/server/solon/service/ServerService.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.solon.service; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.dromara.mica.mqtt.server.solon.MqttServerTemplate; 5 | import org.noear.solon.annotation.Component; 6 | import org.noear.solon.annotation.Inject; 7 | 8 | import java.nio.charset.StandardCharsets; 9 | 10 | /** 11 | * @author wsq 12 | */ 13 | @Slf4j 14 | @Component 15 | public class ServerService { 16 | @Inject 17 | private MqttServerTemplate server; 18 | 19 | public boolean publish(String body) { 20 | boolean result = server.publishAll("/test/123", body.getBytes(StandardCharsets.UTF_8)); 21 | log.info("Mqtt publishAll result:{}", result); 22 | return result; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/auth/MqttSubscribeValidator.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.auth; 2 | 3 | import org.dromara.mica.mqtt.codec.MqttQoS; 4 | import org.dromara.mica.mqtt.core.server.auth.IMqttServerSubscribeValidator; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.tio.core.ChannelContext; 7 | 8 | /** 9 | * 示例自定义订阅校验,请按照自己的需求和业务进行扩展 10 | * 11 | * @author L.cm 12 | */ 13 | @Configuration(proxyBeanMethods = false) 14 | public class MqttSubscribeValidator implements IMqttServerSubscribeValidator { 15 | 16 | @Override 17 | public boolean isValid(ChannelContext context, String clientId, String topicFilter, MqttQoS qoS) { 18 | // 校验客户端订阅的 topic,校验成功返回 true,失败返回 false 19 | return true; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ServerService.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.service; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.dromara.mica.mqtt.spring.server.MqttServerTemplate; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.nio.charset.StandardCharsets; 9 | 10 | /** 11 | * @author wsq 12 | */ 13 | @Slf4j 14 | @Service 15 | public class ServerService { 16 | @Autowired 17 | private MqttServerTemplate server; 18 | 19 | public boolean publish(String body) { 20 | boolean result = server.publishAll("/test/123", body.getBytes(StandardCharsets.UTF_8)); 21 | log.info("Mqtt publishAll result:{}", result); 22 | return result; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-solon-plugin/src/test/java/org/dromara/mica/mqtt/server/solon/test/task/task/PublishAllTask.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.solon.test.task.task; 2 | 3 | import org.dromara.mica.mqtt.server.solon.MqttServerTemplate; 4 | import org.noear.solon.annotation.Component; 5 | import org.noear.solon.annotation.Inject; 6 | import org.noear.solon.scheduling.annotation.Scheduled; 7 | 8 | import java.nio.charset.StandardCharsets; 9 | 10 | /** 11 | * @author wsq 12 | */ 13 | @Component 14 | public class PublishAllTask { 15 | @Inject 16 | private MqttServerTemplate mqttServerTemplate; 17 | 18 | @Scheduled(fixedDelay = 1000) 19 | public void run() { 20 | boolean b = mqttServerTemplate.publishAll("/test/123", "mica最牛皮".getBytes(StandardCharsets.UTF_8)); 21 | System.out.println(b); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/PublishAllTask.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.task; 2 | 3 | import org.dromara.mica.mqtt.core.server.MqttServer; 4 | import org.dromara.mica.mqtt.server.pojo.User; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.scheduling.annotation.Scheduled; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.nio.charset.StandardCharsets; 10 | 11 | /** 12 | * @author wsq 13 | */ 14 | @Service 15 | public class PublishAllTask { 16 | @Autowired 17 | private MqttServer mqttServer; 18 | 19 | @Scheduled(fixedDelay = 1000) 20 | public void run() { 21 | mqttServer.publishAll("/test/123", "mica最牛皮".getBytes(StandardCharsets.UTF_8)); 22 | mqttServer.publishAll("/test/object", User.newUser()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/test/java/org/dromara/mica/mqtt/core/util/TestBean.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.util; 2 | 3 | public class TestBean { 4 | private String name; 5 | private String node; 6 | private String clientId; 7 | 8 | public String getName() { 9 | return name; 10 | } 11 | 12 | public void setName(String name) { 13 | this.name = name; 14 | } 15 | 16 | public String getNode() { 17 | return node; 18 | } 19 | 20 | public void setNode(String node) { 21 | this.node = node; 22 | } 23 | 24 | public String getClientId() { 25 | return clientId; 26 | } 27 | 28 | public void setClientId(String clientId) { 29 | this.clientId = clientId; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "TestBean{" + 35 | "name='" + name + '\'' + 36 | ", node='" + node + '\'' + 37 | ", clientId='" + clientId + '\'' + 38 | '}'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/server/solon/task/PublishTask.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.solon.task; 2 | 3 | import org.dromara.mica.mqtt.server.solon.MqttServerTemplate; 4 | import org.dromara.mica.mqtt.server.solon.pojo.User; 5 | import org.noear.solon.annotation.Component; 6 | import org.noear.solon.annotation.Inject; 7 | import org.noear.solon.scheduling.annotation.Scheduled; 8 | 9 | import java.nio.charset.StandardCharsets; 10 | 11 | /** 12 | * @author wsq 13 | */ 14 | @Component 15 | public class PublishTask { 16 | @Inject 17 | private MqttServerTemplate mqttServerTemplate; 18 | 19 | @Scheduled(fixedDelay = 1000) 20 | public void publish() { 21 | mqttServerTemplate.publishAll("/test/123", "mica最牛皮".getBytes(StandardCharsets.UTF_8)); 22 | mqttServerTemplate.publishAll("/test/object", User.newUser()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/test/java/org/dromara/mica/mqtt/core/timer/SystemTimerTest.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.timer; 2 | 3 | import org.dromara.mica.mqtt.core.util.timer.AckTimerTask; 4 | import org.tio.utils.timer.SystemTimer; 5 | import org.tio.utils.timer.TimingWheelThread; 6 | 7 | import java.util.concurrent.TimeUnit; 8 | 9 | public class SystemTimerTest { 10 | 11 | public static void main(String[] args) throws InterruptedException { 12 | SystemTimer systemTimer = new SystemTimer("timer"); 13 | 14 | TimingWheelThread timingWheelThread = new TimingWheelThread(systemTimer); 15 | timingWheelThread.start(); 16 | 17 | System.out.println(System.currentTimeMillis()); 18 | systemTimer.add(new AckTimerTask(systemTimer, () -> { 19 | System.out.println("hello!"); 20 | }, 5, 5)); 21 | System.out.println(System.nanoTime()); 22 | 23 | TimeUnit.MINUTES.sleep(10L); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/test/java/org/dromara/mica/mqtt/core/udp/UdpClusterTest1.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.udp; 2 | 3 | import java.io.IOException; 4 | import java.util.Timer; 5 | import java.util.TimerTask; 6 | 7 | /** 8 | * @author L.cm 9 | */ 10 | public class UdpClusterTest1 { 11 | 12 | public static void main(String[] args) throws IOException { 13 | UdpTestHandler udpTestHandler = new UdpTestHandler(); 14 | UdpClusterConfig udpServerConf = new UdpClusterConfig("224.0.0.1", 12345, udpTestHandler, 5000); 15 | UdpCluster udpCluster = new UdpCluster(udpServerConf); 16 | udpCluster.start(); 17 | 18 | byte[] buffer = "hello1".getBytes(); 19 | TimerTask timerTask = new TimerTask() { 20 | @Override 21 | public void run() { 22 | udpCluster.send(buffer); 23 | } 24 | }; 25 | 26 | Timer timer = new Timer(); 27 | timer.schedule(timerTask, 1000, 1000); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### gradle ### 2 | .gradle 3 | !gradle/wrapper/gradle-wrapper.jar 4 | 5 | ### STS ### 6 | .settings/ 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | bin/ 14 | 15 | ### IntelliJ IDEA ### 16 | !.idea/icon.png 17 | .idea 18 | out/ 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | nbproject/private/ 25 | build/ 26 | nbbuild/ 27 | dist/ 28 | nbdist/ 29 | .nb-gradle/ 30 | 31 | ### vscode ### 32 | .vscode 33 | 34 | ### maven ### 35 | target/ 36 | *.war 37 | *.ear 38 | *.zip 39 | *.tar 40 | *.tar.gz 41 | 42 | # logs # 43 | logs 44 | 45 | # temp ignore 46 | *.log 47 | *.cache 48 | *.diff 49 | *.patch 50 | *.tmp 51 | *.java~ 52 | *.properties~ 53 | *.xml~ 54 | 55 | # system ignore 56 | .DS_Store 57 | Thumbs.db 58 | Servers 59 | .metadata 60 | upload 61 | gen_code 62 | 63 | # Flattened pom 64 | .flattened-pom.xml 65 | /**/.flattened-pom.xml 66 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/test/java/org/dromara/mica/mqtt/core/udp/UdpClusterTest2.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.udp; 2 | 3 | import java.io.IOException; 4 | import java.util.Timer; 5 | import java.util.TimerTask; 6 | 7 | /** 8 | * @author L.cm 9 | */ 10 | public class UdpClusterTest2 { 11 | 12 | public static void main(String[] args) throws IOException { 13 | UdpTestHandler udpTestHandler = new UdpTestHandler(); 14 | UdpClusterConfig udpServerConf = new UdpClusterConfig("224.0.0.1", 12345, udpTestHandler, 5000); 15 | UdpCluster udpCluster = new UdpCluster(udpServerConf); 16 | udpCluster.start(); 17 | 18 | byte[] buffer = "hello2".getBytes(); 19 | TimerTask timerTask = new TimerTask() { 20 | @Override 21 | public void run() { 22 | udpCluster.send(buffer); 23 | } 24 | }; 25 | 26 | Timer timer = new Timer(); 27 | timer.schedule(timerTask, 1000, 1000); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/java/org/dromara/mica/mqtt/client/listener/OtherMqttClientSubscribeListener.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.listener; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 5 | import org.dromara.mica.mqtt.core.annotation.MqttClientSubscribe; 6 | import org.springframework.stereotype.Service; 7 | 8 | /** 9 | * 客户端消息监听,注解在方法上 10 | * 11 | * @author L.cm 12 | */ 13 | @Slf4j 14 | @Service 15 | public class OtherMqttClientSubscribeListener { 16 | 17 | @MqttClientSubscribe( 18 | value = { 19 | "$share/iothub/test/${a}", 20 | "/test/${arg1}/${arg2}/${arg3}/${arg4}" 21 | }, 22 | clientTemplateBean = "mqttClientTemplate1" 23 | ) 24 | public void sub(String topic, MqttPublishMessage message, byte[] payload) { 25 | log.info("topic:{} payload:{}", topic, new String(payload)); 26 | } 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/test/java/org/dromara/mica/mqtt/core/udp/UdpClusterConfig.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.udp; 2 | 3 | import org.tio.core.Node; 4 | import org.tio.core.udp.UdpConf; 5 | import org.tio.core.udp.intf.UdpHandler; 6 | 7 | public class UdpClusterConfig extends UdpConf { 8 | private UdpHandler udpHandler; 9 | private int readBufferSize = 1024 * 1024; 10 | 11 | public UdpClusterConfig(String ip, int port, UdpHandler udpHandler, int timeout) { 12 | super(timeout); 13 | this.setUdpHandler(udpHandler); 14 | this.setServerNode(new Node(ip, port)); 15 | } 16 | 17 | public int getReadBufferSize() { 18 | return readBufferSize; 19 | } 20 | 21 | public UdpHandler getUdpHandler() { 22 | return udpHandler; 23 | } 24 | 25 | public void setReadBufferSize(int readBufferSize) { 26 | this.readBufferSize = readBufferSize; 27 | } 28 | 29 | public void setUdpHandler(UdpHandler udpHandler) { 30 | this.udpHandler = udpHandler; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-solon-plugin/src/test/resources/app.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 30033 3 | # mqtt 服务端配置 4 | mqtt: 5 | server: 6 | enabled: true # 是否开启服务端,默认:true 7 | name: Mica-Mqtt-Server # 名称,默认:Mica-Mqtt-Server 8 | heartbeat-timeout: 120000 # 心跳超时,单位毫秒,默认: 1000 * 120 9 | read-buffer-size: 8KB # 接收数据的 buffer size,默认:8k 10 | max-bytes-in-message: 10MB # 消息解析最大 bytes 长度,默认:10M 11 | auth: 12 | enable: false # 是否开启 mqtt 认证 13 | username: mica # mqtt 认证用户名 14 | password: mica # mqtt 认证密码 15 | debug: true # 如果开启 prometheus 指标收集建议关闭 16 | stat-enable: true # 开启指标收集,debug 和 prometheus 开启时需要打开,默认开启,关闭节省内存 17 | mqtt-listener: # mqtt 监听器,还有 mqtt-ssl-listener 18 | enable: true # 是否开启,默认:false 19 | # ip: "0.0.0.0" # 服务端 ip 默认为空,0.0.0.0,建议不要设置 20 | port: 1883 # 端口,默认:1883 21 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/client/solon/service/ClientService.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.solon.service; 2 | 3 | 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.dromara.mica.mqtt.client.solon.MqttClientTemplate; 6 | import org.noear.solon.annotation.Component; 7 | import org.noear.solon.annotation.Inject; 8 | 9 | import java.nio.charset.StandardCharsets; 10 | 11 | /** 12 | * @author wsq 13 | */ 14 | @Slf4j 15 | @Component 16 | public class ClientService { 17 | @Inject 18 | private MqttClientTemplate client; 19 | 20 | public boolean publish(String body) { 21 | client.publish("/test/client", body.getBytes(StandardCharsets.UTF_8)); 22 | return true; 23 | } 24 | 25 | public boolean sub() { 26 | client.subQos0("/test/#", (context, topic, message, payload) -> { 27 | log.info("{}\t{}", topic, new String(payload, StandardCharsets.UTF_8)); 28 | }); 29 | return true; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/client/solon/listener/MqttClientMessageListener.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.solon.listener; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.dromara.mica.mqtt.core.annotation.MqttClientSubscribe; 5 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 6 | import org.dromara.mica.mqtt.core.client.IMqttClientMessageListener; 7 | import org.tio.core.ChannelContext; 8 | 9 | import java.nio.charset.StandardCharsets; 10 | 11 | /** 12 | * 客户端消息监听的另一种方式 13 | * 14 | * @author L.cm 15 | */ 16 | @Slf4j 17 | @MqttClientSubscribe("${topic1}") 18 | public class MqttClientMessageListener implements IMqttClientMessageListener { 19 | 20 | @Override 21 | public void onMessage(ChannelContext context, String topic, MqttPublishMessage message, byte[] payload) { 22 | log.info("MqttClientMessageListener,topic:{} payload:{}", topic, new String(payload, StandardCharsets.UTF_8)); 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/resources/ssl/client-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXQIBAAKBgQC94R9L0WArKrO/YIVD7JIK/m0MlZDv+lNR9eMhyVslnl09rZfl 3 | U714aLtGZN8mLXejt5duNT4JgI8AQz8n5jNlFP85bl0MxCxLnwJwuENsJdL6aI+5 4 | hkHjLkaY2TdxW5UtG0Yn73Lcd7m1lb0swhSGii2YHa58lpuS5pCUI0WhAwIDAQAB 5 | AoGAR/T8azsZesJgA/KMDkWkws3QfahgmNEAqlrIjJFGHWd6ZllW6u1lLDBkaDTp 6 | 7AnnAQAePwGmVOuHRc42LOSsLMX/D2wYsTGjLTT1w+fEDkQCVnDKV8ZYWA5fN7Zh 7 | m5cLB5IB23L/Xvs8UMYQ8qWufv6BxVPr+cawtXOK3O91AoECQQD5PwGSrMpsNkVG 8 | Ox1t1A9wVgelbq+9qANPl8TvdaZKvNsbWwI0PRqK7D1SJXJiMX4m/hc8YkIXJWsO 9 | Wd1yLg6TAkEAwwZLncJYlYOp0v8PXk75rDR7KV9fdBPPOdnZ1XU/yFW3anwOt0OX 10 | LvGL3X0A2f/tqOX9v+3LENCICF4gAv850QJBALo7Yal+giEoy8oWEX8mnAKLxVrO 11 | wXEsQI0QEY36ki31vqFJ9vOhVFvI+GiQok7MPD5WTHZJ1KgGxV8LtnLCBxECQCPD 12 | WcZ6RyhT1qaco0LWFK7hiNxTYvu0TkH7kxizwZiJL3NVgJVWzbiMDuv06l0Ps5NP 13 | abLydlSFCQ0PxasHBqECQQC0lhmqkNbaN3lJyGDoEWm6Kb9z3eh3+9Fk4j328aYW 14 | gQcBeRhKU8kdDTg2flOWS3sxrEysJYv8i9DPbX9RsRFd 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/java/org/dromara/mica/mqtt/client/listener/MqttClientMessageListener.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.listener; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 5 | import org.dromara.mica.mqtt.core.client.IMqttClientMessageListener; 6 | import org.dromara.mica.mqtt.core.annotation.MqttClientSubscribe; 7 | import org.springframework.stereotype.Service; 8 | import org.tio.core.ChannelContext; 9 | 10 | import java.nio.charset.StandardCharsets; 11 | 12 | /** 13 | * 客户端消息监听的另一种方式 14 | * 15 | * @author L.cm 16 | */ 17 | @Slf4j 18 | @Service 19 | @MqttClientSubscribe("${topic1}") 20 | public class MqttClientMessageListener implements IMqttClientMessageListener { 21 | 22 | @Override 23 | public void onMessage(ChannelContext context, String topic, MqttPublishMessage message, byte[] payload) { 24 | log.info("topic:{} payload:{}", topic, new String(payload, StandardCharsets.UTF_8)); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/controller/ServerController.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.controller; 2 | 3 | import io.swagger.v3.oas.annotations.Operation; 4 | import io.swagger.v3.oas.annotations.tags.Tag; 5 | import org.dromara.mica.mqtt.server.service.ServerService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | @Tag(name = "Mqtt::服务端") 13 | @RequestMapping("/mqtt/server") 14 | @RestController 15 | public class ServerController { 16 | @Autowired 17 | private ServerService service; 18 | 19 | @Operation(summary = "publish") 20 | @PostMapping("publish") 21 | public boolean publish(@RequestBody String body) { 22 | return service.publish(body); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/resources/ssl/ca-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICejCCAeMCFGkzqgl8ilICj+PRCwIiUy3dPNuWMA0GCSqGSIb3DQEBCwUAMHwx 3 | CzAJBgNVBAYTAkNOMQswCQYDVQQIDAJITjELMAkGA1UEBwwCQ1MxDTALBgNVBAoM 4 | BFJNSlMxDTALBgNVBAsMBFJNSlMxFDASBgNVBAMMC2RyZWFtbHUubmV0MR8wHQYJ 5 | KoZIhvcNAQkBFhA1OTYzOTI5MTJAcXEuY29tMB4XDTIyMDkwMzA4MjExNVoXDTMy 6 | MDgzMTA4MjExNVowfDELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkhOMQswCQYDVQQH 7 | DAJDUzENMAsGA1UECgwEUk1KUzENMAsGA1UECwwEUk1KUzEUMBIGA1UEAwwLZHJl 8 | YW1sdS5uZXQxHzAdBgkqhkiG9w0BCQEWEDU5NjM5MjkxMkBxcS5jb20wgZ8wDQYJ 9 | KoZIhvcNAQEBBQADgY0AMIGJAoGBAJxanDadRHd+D9jH5/mq7Pn3Fl915CiOaaJr 10 | QS0ZxCqRtTaS9+JkFQJ4TnAezlKx/xDZu7G9pk7CJ6w+JQwfI+AwsAkOlrynyFbe 11 | Hc9s6DZyZHXxkpgeQUqpnrkXkWG+jbh2aulWB4smQE/vPnpkjVGEe86+/JsYW3Sm 12 | rFhL2xddAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAP39PM0XpNzg3Bne63oXHRWDJ 13 | bafiCwloO/SaxH7JtCBj1I05W3owwHSqWYadK+lg//tKf6TL+94GtW8s2VtpLGu7 14 | Y5R2aakhywzbWVfrEK+kyvTG/4nP9tvcKwh8Iqr2XlllDLfsQeyLacb4+pcfDY3G 15 | 8nrbe0lBKepae8D0SvQ= 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/resources/ssl/client-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICejCCAeMCFBebamYN4nfF0CrZWuN68SXxTH/GMA0GCSqGSIb3DQEBCwUAMHwx 3 | CzAJBgNVBAYTAkNOMQswCQYDVQQIDAJITjELMAkGA1UEBwwCQ1MxDTALBgNVBAoM 4 | BFJNSlMxDTALBgNVBAsMBFJNSlMxFDASBgNVBAMMC2RyZWFtbHUubmV0MR8wHQYJ 5 | KoZIhvcNAQkBFhA1OTYzOTI5MTJAcXEuY29tMB4XDTIyMDkwMzA4MjM1N1oXDTMy 6 | MDgzMTA4MjM1N1owfDELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkhOMQswCQYDVQQH 7 | DAJDUzENMAsGA1UECgwEUk1KUzENMAsGA1UECwwEUk1KUzEUMBIGA1UEAwwLZHJl 8 | YW1sdS5uZXQxHzAdBgkqhkiG9w0BCQEWEDU5NjM5MjkxMkBxcS5jb20wgZ8wDQYJ 9 | KoZIhvcNAQEBBQADgY0AMIGJAoGBAL3hH0vRYCsqs79ghUPskgr+bQyVkO/6U1H1 10 | 4yHJWyWeXT2tl+VTvXhou0Zk3yYtd6O3l241PgmAjwBDPyfmM2UU/zluXQzELEuf 11 | AnC4Q2wl0vpoj7mGQeMuRpjZN3FblS0bRifvctx3ubWVvSzCFIaKLZgdrnyWm5Lm 12 | kJQjRaEDAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAkm/Mv9nEGE4xy3L4NmwgyZMo 13 | j5CuarbCEv/MgXST8B/dJvtC7PbCzrb9BbUkiIUjCOnRC+2U0DbSAkHy7CCwHTLx 14 | g9Syn1SMWn9SF74l74qVtuaRjMKCGwSlqBLH5/t1FdPoevY2a+zi5dAqwIhkjY84 15 | uYOgxODe+kFBUbT6W3A= 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/MqttConst.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server; 18 | 19 | /** 20 | * 常量 21 | * 22 | * @author L.cm 23 | */ 24 | public interface MqttConst { 25 | 26 | /** 27 | * session 有效期,小于等于 0,关闭时清理,大于 0 采用缓存处理 28 | */ 29 | String SESSION_EXPIRES = "session_expires"; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/src/test/java/org/dromara/mica/mqtt/client/solon/test/ClientTest.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.solon.test; 2 | 3 | import org.dromara.mica.mqtt.client.solon.MqttClientTemplate; 4 | import org.noear.solon.Solon; 5 | import org.noear.solon.annotation.Component; 6 | import org.noear.solon.annotation.Inject; 7 | import org.noear.solon.core.event.AppLoadEndEvent; 8 | import org.noear.solon.core.event.EventListener; 9 | 10 | import java.nio.charset.StandardCharsets; 11 | 12 | /** 13 | * (ClientTest) 14 | * 15 | * @author Peigen 16 | * @version 1.0.0 17 | * @since 2023/7/15 18 | */ 19 | @Component 20 | public class ClientTest implements EventListener { 21 | public static void main(String[] args) { 22 | Solon.start(ClientTest.class, args); 23 | } 24 | 25 | @Inject 26 | MqttClientTemplate client; 27 | 28 | @Override 29 | public void onEvent(AppLoadEndEvent event) throws Throwable { 30 | client.publish("mica", "hello".getBytes(StandardCharsets.UTF_8)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-jfinal-plugin/README.md: -------------------------------------------------------------------------------- 1 | # jfinal mica-mqtt-server 2 | 3 | ## 使用 4 | 5 | #### 1. 添加依赖 6 | ```xml 7 | 8 | org.dromara.mica-mqtt 9 | mica-mqtt-server-jfinal-plugin 10 | ${最新版本} 11 | 12 | ``` 13 | 14 | #### 2. 删除 jfinal-demo 中的 slf4j-nop 依赖 15 | 16 | #### 3. 添加 slf4j-log4j12 17 | ```xml 18 | 19 | org.slf4j 20 | slf4j-log4j12 21 | 1.7.33 22 | 23 | ``` 24 | 25 | #### 4. 插件配置 26 | ```java 27 | MqttServerPlugin plugin = new MqttServerPlugin(); 28 | plugin.config(mqttServerCreator -> { 29 | // mqttServerCreator 上有很多方法,详见 mica-mqtt-core 30 | mqttServerCreator 31 | .enableMqtt() 32 | .enableMqttWs() 33 | .enableMqttHttpApi() 34 | ; 35 | }); 36 | plugin.start(); 37 | ``` 38 | 39 | #### 5. 插件使用 40 | ```java 41 | // 更多方法可以直接使用 MqttServerKit 点出来 42 | MqttServerKit.publish(String clientId, String topic, byte[] payload); 43 | ``` -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/java/org/dromara/mica/mqtt/client/controller/ClientController.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.controller; 2 | 3 | import io.swagger.v3.oas.annotations.Operation; 4 | import io.swagger.v3.oas.annotations.tags.Tag; 5 | import org.dromara.mica.mqtt.client.service.ClientService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | @Tag(name = "Mqtt::客户端") 10 | @RequestMapping("/mqtt/client") 11 | @RestController 12 | public class ClientController { 13 | 14 | @Autowired 15 | private ClientService service; 16 | 17 | @Operation(summary = "publish") 18 | @PostMapping("/publish") 19 | public boolean publish(@RequestBody String body) { 20 | service.publish(body); 21 | service.publishHelloInterfaceA(body); 22 | service.publishHelloInterfaceB(body); 23 | return true; 24 | } 25 | 26 | @Operation(summary = "sub") 27 | @GetMapping("/sub") 28 | public boolean sub() { 29 | return service.sub(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | ${AnsiColor.BRIGHT_BLUE}## ## #### ###### ### ${AnsiColor.RED} ## ## ####### ######## ######## 3 | ${AnsiColor.BRIGHT_BLUE}### ### ## ## ## ## ## ${AnsiColor.RED} ### ### ## ## ## ## 4 | ${AnsiColor.BRIGHT_BLUE}#### #### ## ## ## ## ${AnsiColor.RED} #### #### ## ## ## ## 5 | ${AnsiColor.BRIGHT_BLUE}## ### ## ## ## ## ##${AnsiColor.RED} ## ### ## ## ## ## ## 6 | ${AnsiColor.BRIGHT_BLUE}## ## ## ## #########${AnsiColor.RED} ## ## ## ## ## ## ## 7 | ${AnsiColor.BRIGHT_BLUE}## ## ## ## ## ## ##${AnsiColor.RED} ## ## ## ## ## ## 8 | ${AnsiColor.BRIGHT_BLUE}## ## #### ###### ## ##${AnsiColor.RED} ## ## ##### ## ## ## 9 | 10 | https://www.dreamlu.net 11 | 12 | ${AnsiColor.BRIGHT_BLUE}:: ${spring.application.name} :: Running Spring Boot ${spring-boot.version} 🏃🏃🏃 ${AnsiColor.DEFAULT} 13 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/server/solon/listener/MqttServerMessageListener1.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.solon.listener; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 5 | import org.dromara.mica.mqtt.codec.MqttQoS; 6 | import org.dromara.mica.mqtt.core.server.event.IMqttMessageListener; 7 | import org.tio.core.ChannelContext; 8 | 9 | import java.nio.charset.StandardCharsets; 10 | 11 | /** 12 | * 消息监听器示例1,直接实现 IMqttMessageListener,注意:如果实现了 IMqttMessageListener,MqttServerFunction 注解就不生效了。 13 | * 14 | * @author wsq 15 | */ 16 | @Slf4j 17 | //@Component 18 | public class MqttServerMessageListener1 implements IMqttMessageListener { 19 | 20 | @Override 21 | public void onMessage(ChannelContext context, String clientId, String topic, MqttQoS qos, MqttPublishMessage message) { 22 | log.info("context:{} clientId:{} message:{} payload:{}", context, clientId, message, new String(message.payload(), StandardCharsets.UTF_8)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | ${AnsiColor.BRIGHT_BLUE}## ## #### ###### ### ${AnsiColor.RED} ## ## ####### ######## ######## 3 | ${AnsiColor.BRIGHT_BLUE}### ### ## ## ## ## ## ${AnsiColor.RED} ### ### ## ## ## ## 4 | ${AnsiColor.BRIGHT_BLUE}#### #### ## ## ## ## ${AnsiColor.RED} #### #### ## ## ## ## 5 | ${AnsiColor.BRIGHT_BLUE}## ### ## ## ## ## ##${AnsiColor.RED} ## ### ## ## ## ## ## 6 | ${AnsiColor.BRIGHT_BLUE}## ## ## ## #########${AnsiColor.RED} ## ## ## ## ## ## ## 7 | ${AnsiColor.BRIGHT_BLUE}## ## ## ## ## ## ##${AnsiColor.RED} ## ## ## ## ## ## 8 | ${AnsiColor.BRIGHT_BLUE}## ## #### ###### ## ##${AnsiColor.RED} ## ## ##### ## ## ## 9 | 10 | https://www.dreamlu.net 11 | 12 | ${AnsiColor.BRIGHT_BLUE}:: ${spring.application.name} :: Running Spring Boot ${spring-boot.version} 🏃🏃🏃 ${AnsiColor.DEFAULT} 13 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/serializer/MqttSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.serializer; 18 | 19 | /** 20 | * mqtt 消息序列化 21 | * 22 | * @author L.cm 23 | */ 24 | public interface MqttSerializer { 25 | 26 | /** 27 | * 序列化 28 | * 29 | * @param message message 30 | * @return byte 数组 31 | */ 32 | byte[] serialize(Object message); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/src/test/java/org/dromara/mica/mqtt/client/solon/test/listener/MqttClientMessageListener.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.solon.test.listener; 2 | 3 | import org.dromara.mica.mqtt.core.annotation.MqttClientSubscribe; 4 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 5 | import org.dromara.mica.mqtt.core.client.IMqttClientMessageListener; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.tio.core.ChannelContext; 9 | 10 | import java.nio.charset.StandardCharsets; 11 | 12 | /** 13 | * 客户端消息监听的另一种方式 14 | * 15 | * @author L.cm 16 | */ 17 | @MqttClientSubscribe("${topic1}") 18 | public class MqttClientMessageListener implements IMqttClientMessageListener { 19 | private static final Logger logger = LoggerFactory.getLogger(MqttClientMessageListener.class); 20 | 21 | @Override 22 | public void onMessage(ChannelContext context, String topic, MqttPublishMessage message, byte[] payload) { 23 | logger.info("topic:{} payload:{}", topic, new String(payload, StandardCharsets.UTF_8)); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/java/org/dromara/mica/mqtt/client/config/OtherMqttClientConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.config; 2 | 3 | import org.dromara.mica.mqtt.core.client.DefaultMqttClientSession; 4 | import org.dromara.mica.mqtt.core.client.MqttClientCreator; 5 | import org.dromara.mica.mqtt.spring.client.MqttClientTemplate; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * 示例多个 mqtt client 11 | * 12 | * @author L.cm 13 | */ 14 | @Configuration 15 | public class OtherMqttClientConfiguration { 16 | 17 | @Bean("mqttClientTemplate1") 18 | public MqttClientTemplate mqttClientTemplate1() { 19 | // 基于 clientCreator 的配置构建一个新的 20 | MqttClientCreator mqttClientCreator1 = new MqttClientCreator() 21 | // 修改不同的配置 22 | // .ip("mqtt.dreamlu.net") 23 | .port(1884) 24 | .username("mica") 25 | .password("mica") 26 | // 避免 client session 冲突 27 | .clientSession(new DefaultMqttClientSession()); 28 | return new MqttClientTemplate(mqttClientCreator1); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/test/java/org/dromara/mica/mqtt/core/udp/UdpTestHandler.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.udp; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.tio.core.Node; 6 | import org.tio.core.udp.UdpPacket; 7 | import org.tio.core.udp.intf.UdpHandler; 8 | 9 | import java.net.DatagramPacket; 10 | import java.net.DatagramSocket; 11 | 12 | /** 13 | * @author tanyaowu 14 | */ 15 | public class UdpTestHandler implements UdpHandler { 16 | private static final Logger log = LoggerFactory.getLogger(UdpTestHandler.class); 17 | 18 | public UdpTestHandler() { 19 | } 20 | 21 | @Override 22 | public void handler(UdpPacket udpPacket, DatagramSocket datagramSocket) { 23 | byte[] data = udpPacket.getData(); 24 | String msg = new String(data); 25 | Node remote = udpPacket.getRemote(); 26 | 27 | System.out.printf("收到来自%s的消息:【%s】%n", remote, msg); 28 | DatagramPacket datagramPacket = new DatagramPacket(data, data.length); 29 | try { 30 | datagramSocket.send(datagramPacket); 31 | } catch (Throwable e) { 32 | log.error(e.toString(), e); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | open module org.dromara.mica.mqtt.server { 2 | requires transitive org.dromara.mica.mqtt.common; 3 | requires transitive net.dreamlu.mica.net.http; 4 | requires java.management; 5 | 6 | exports org.dromara.mica.mqtt.core.server; 7 | exports org.dromara.mica.mqtt.core.server.auth; 8 | exports org.dromara.mica.mqtt.core.server.broker; 9 | exports org.dromara.mica.mqtt.core.server.cluster; 10 | exports org.dromara.mica.mqtt.core.server.dispatcher; 11 | exports org.dromara.mica.mqtt.core.server.enums; 12 | exports org.dromara.mica.mqtt.core.server.event; 13 | exports org.dromara.mica.mqtt.core.server.http.handler; 14 | exports org.dromara.mica.mqtt.core.server.interceptor; 15 | exports org.dromara.mica.mqtt.core.server.listener; 16 | exports org.dromara.mica.mqtt.core.server.model; 17 | exports org.dromara.mica.mqtt.core.server.protocol; 18 | exports org.dromara.mica.mqtt.core.server.serializer; 19 | exports org.dromara.mica.mqtt.core.server.session; 20 | exports org.dromara.mica.mqtt.core.server.store; 21 | exports org.dromara.mica.mqtt.core.server.support; 22 | } 23 | -------------------------------------------------------------------------------- /mica-mqtt-client/src/main/java/org/dromara/mica/mqtt/core/client/MqttClientCustomizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.client; 18 | 19 | /** 20 | * MqttClient 配置自定义 21 | * 22 | * @author L.cm 23 | */ 24 | @FunctionalInterface 25 | public interface MqttClientCustomizer { 26 | 27 | /** 28 | * MqttServerCreator 自定义扩展 29 | * 30 | * @param creator MqttClientCreator 31 | */ 32 | void customize(MqttClientCreator creator); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/MqttServerCustomizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server; 18 | 19 | /** 20 | * MqttServer 配置自定义 21 | * 22 | * @author L.cm 23 | */ 24 | @FunctionalInterface 25 | public interface MqttServerCustomizer { 26 | 27 | /** 28 | * MqttServerCreator 自定义扩展 29 | * 30 | * @param creator MqttServerCreator 31 | */ 32 | void customize(MqttServerCreator creator); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/serializer/MqttJsonSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.serializer; 18 | 19 | import org.tio.utils.json.JsonUtil; 20 | 21 | /** 22 | * mqtt 消息 json 序列化 23 | * 24 | * @author L.cm 25 | */ 26 | public class MqttJsonSerializer implements MqttSerializer { 27 | 28 | @Override 29 | public byte[] serialize(Object message) { 30 | return JsonUtil.toJsonBytes(message); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/test/java/org/dromara/mica/mqtt/core/server/test/cluster/ClusterTest2.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.server.test.cluster; 2 | 3 | import org.tio.server.cluster.core.ClusterApi; 4 | import org.tio.server.cluster.core.ClusterConfig; 5 | import org.tio.server.cluster.core.ClusterImpl; 6 | 7 | import java.nio.charset.StandardCharsets; 8 | 9 | /** 10 | * 集群开发测试 11 | * 12 | * @author L.cm 13 | */ 14 | public class ClusterTest2 { 15 | 16 | public static void main(String[] args) throws Exception { 17 | ClusterConfig config = new ClusterConfig("127.0.0.1", 3002, message -> { 18 | System.out.println(new String(message.getPayload())); 19 | }); 20 | 21 | config.addSeedMember("127.0.0.1", 3001); 22 | config.addSeedMember("127.0.0.1", 3002); 23 | config.addSeedMember("127.0.0.1", 3003); 24 | 25 | ClusterApi cluster = new ClusterImpl(config); 26 | cluster.start(); 27 | 28 | cluster.schedule(() -> { 29 | String message = String.format("hello mica form cluster:%s ns:%s", cluster.getLocalMember(), System.nanoTime()); 30 | cluster.broadcast(message.getBytes(StandardCharsets.UTF_8)); 31 | }, 3000); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/test/java/org/dromara/mica/mqtt/core/server/test/cluster/ClusterTest3.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.server.test.cluster; 2 | 3 | import org.tio.server.cluster.core.ClusterApi; 4 | import org.tio.server.cluster.core.ClusterConfig; 5 | import org.tio.server.cluster.core.ClusterImpl; 6 | 7 | import java.nio.charset.StandardCharsets; 8 | 9 | /** 10 | * 集群开发测试 11 | * 12 | * @author L.cm 13 | */ 14 | public class ClusterTest3 { 15 | 16 | public static void main(String[] args) throws Exception { 17 | ClusterConfig config = new ClusterConfig("127.0.0.1", 3003, message -> { 18 | System.out.println(new String(message.getPayload())); 19 | }); 20 | 21 | config.addSeedMember("127.0.0.1", 3001); 22 | config.addSeedMember("127.0.0.1", 3002); 23 | config.addSeedMember("127.0.0.1", 3003); 24 | 25 | ClusterApi cluster = new ClusterImpl(config); 26 | cluster.start(); 27 | 28 | cluster.schedule(() -> { 29 | String message = String.format("hello mica form cluster:%s ns:%s", cluster.getLocalMember(), System.nanoTime()); 30 | cluster.broadcast(message.getBytes(StandardCharsets.UTF_8)); 31 | }, 3000); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/http/api/form/SubscribeForm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.http.api.form; 18 | 19 | /** 20 | * 订阅表单 21 | * 22 | * @author L.cm 23 | */ 24 | public class SubscribeForm extends BaseForm { 25 | 26 | /** 27 | * QoS 等级 0 28 | */ 29 | private int qos = 0; 30 | 31 | public int getQos() { 32 | return qos; 33 | } 34 | 35 | public void setQos(int qos) { 36 | this.qos = qos; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/annotation/MqttPayload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.annotation; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * @author ChangJin Wei (魏昌进) 26 | */ 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target(ElementType.PARAMETER) 29 | public @interface MqttPayload { 30 | 31 | } 32 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/session/SharedStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.session; 18 | 19 | /** 20 | * 共享订阅均衡策略 21 | * 22 | * @author L.cm 23 | */ 24 | public enum SharedStrategy { 25 | 26 | /** 27 | * 在所有订阅者中随机选择 28 | */ 29 | random, 30 | /** 31 | * 按照订阅顺序 32 | */ 33 | round_robin, 34 | /** 35 | * 一直发往上次选取的订阅者 36 | */ 37 | sticky, 38 | /** 39 | * 按照发布者 ClientID 的哈希值 40 | */ 41 | hash; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/test/java/org/dromara/mica/mqtt/core/server/test/cluster/ClusterTest4.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.server.test.cluster; 2 | 3 | import org.tio.server.cluster.core.ClusterApi; 4 | import org.tio.server.cluster.core.ClusterConfig; 5 | import org.tio.server.cluster.core.ClusterImpl; 6 | 7 | import java.nio.charset.StandardCharsets; 8 | 9 | /** 10 | * 集群开发测试 11 | * 12 | * @author L.cm 13 | */ 14 | public class ClusterTest4 { 15 | 16 | public static void main(String[] args) throws Exception { 17 | ClusterConfig config = new ClusterConfig("127.0.0.1", 3004, message -> { 18 | System.out.println(new String(message.getPayload())); 19 | }); 20 | 21 | // 不在种子成员里 22 | config.addSeedMember("127.0.0.1", 3001); 23 | config.addSeedMember("127.0.0.1", 3002); 24 | config.addSeedMember("127.0.0.1", 3003); 25 | 26 | ClusterApi cluster = new ClusterImpl(config); 27 | cluster.start(); 28 | 29 | cluster.schedule(() -> { 30 | String message = String.format("hello mica form cluster:%s ns:%s", cluster.getLocalMember(), System.nanoTime()); 31 | cluster.broadcast(message.getBytes(StandardCharsets.UTF_8)); 32 | }, 3000); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/common/TopicTemplate.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.common; 2 | 3 | import org.tio.utils.mica.StrTemplateParser; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * topic 模板带 ${var} 变量的模板 9 | * 10 | * @author L.cm 11 | */ 12 | public class TopicTemplate { 13 | private final StrTemplateParser templateParser; 14 | private final String topicFilter; 15 | private final TopicFilterType type; 16 | 17 | public TopicTemplate(String topicTemplate, String topicFilter) { 18 | this.templateParser = new StrTemplateParser(topicTemplate); 19 | this.topicFilter = topicFilter; 20 | this.type = TopicFilterType.getType(topicFilter); 21 | } 22 | 23 | /** 24 | * 判断 topicFilter 和 topicName 匹配情况 25 | * 26 | * @param topicName topicName 27 | * @return 是否匹配 28 | */ 29 | public boolean match(String topicName) { 30 | return type.match(this.topicFilter, topicName); 31 | } 32 | 33 | /** 34 | * 解析 topic 中的变量 35 | * 36 | * @param topicName topicName 37 | * @return 变量 38 | */ 39 | public Map getVariables(String topicName) { 40 | return templateParser.getVariables(topicName); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/properties/UserProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.properties; 18 | 19 | public final class UserProperty extends MqttProperty { 20 | public UserProperty(String key, String value) { 21 | super(MqttPropertyType.USER_PROPERTY.value(), new StringPair(key, value)); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "UserProperty(" + value.key + ", " + value.value + ')'; 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/codes/MqttAuthReasonCode.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.codec.codes; 2 | 3 | /** 4 | * Utilities for MQTT message codes enums 5 | * 6 | * @author vertx-mqtt 7 | */ 8 | public enum MqttAuthReasonCode implements MqttReasonCode { 9 | 10 | /** 11 | * Success 12 | */ 13 | SUCCESS((byte) 0x0), 14 | 15 | /** 16 | * Continue Authentication 17 | */ 18 | CONTINUE_AUTHENTICATION((byte) 0x18), 19 | 20 | /** 21 | * Re-Authenticate 22 | */ 23 | RE_AUTHENTICATE((byte) 0x19); 24 | 25 | private final byte byteValue; 26 | 27 | MqttAuthReasonCode(byte byteValue) { 28 | this.byteValue = byteValue; 29 | } 30 | 31 | public static MqttAuthReasonCode valueOf(byte code) { 32 | if (code == SUCCESS.byteValue) { 33 | return SUCCESS; 34 | } else if (code == CONTINUE_AUTHENTICATION.byteValue) { 35 | return CONTINUE_AUTHENTICATION; 36 | } else if (code == RE_AUTHENTICATE.byteValue) { 37 | return RE_AUTHENTICATE; 38 | } else { 39 | throw new IllegalArgumentException("unknown AUTHENTICATE reason code: " + code); 40 | } 41 | } 42 | 43 | @Override 44 | public byte value() { 45 | return byteValue; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/annotation/MqttRetain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.annotation; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * 是否在服务器上保留消息 26 | * @author ChangJin Wei (魏昌进) 27 | */ 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Target(ElementType.PARAMETER) 30 | public @interface MqttRetain { 31 | 32 | } 33 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/test/java/org/dromara/mica/mqtt/core/server/test/cluster/ClusterTest1.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.server.test.cluster; 2 | 3 | import org.tio.server.cluster.core.ClusterApi; 4 | import org.tio.server.cluster.core.ClusterConfig; 5 | import org.tio.server.cluster.core.ClusterImpl; 6 | 7 | import java.nio.charset.StandardCharsets; 8 | 9 | /** 10 | * 集群开发测试 11 | * 12 | * @author L.cm 13 | */ 14 | public class ClusterTest1 { 15 | 16 | public static void main(String[] args) throws Exception { 17 | ClusterConfig config = new ClusterConfig("127.0.0.1", 3001, message -> { 18 | System.out.println(new String(message.getPayload())); 19 | }); 20 | 21 | config.addSeedMember("127.0.0.1", 3001); 22 | config.addSeedMember("127.0.0.1", 3002); 23 | config.addSeedMember("127.0.0.1", 3003); 24 | 25 | // TODO L.cm 思考:是不是不应该无限的对离线重试,对方重新连接触发再重新连接 26 | 27 | ClusterApi cluster = new ClusterImpl(config); 28 | cluster.start(); 29 | 30 | cluster.schedule(() -> { 31 | String message = String.format("hello mica form cluster:%s ns:%s", cluster.getLocalMember(), System.nanoTime()); 32 | cluster.broadcast(message.getBytes(StandardCharsets.UTF_8)); 33 | }, 3000); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/deserialize/MqttDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.deserialize; 18 | 19 | import java.lang.reflect.Type; 20 | 21 | /** 22 | * mqtt 消息反序列化 23 | * 24 | * @author L.cm 25 | * @author ChangJin Wei(魏昌进) 26 | */ 27 | public interface MqttDeserializer { 28 | 29 | /** 30 | * 反序列化 31 | * 32 | * @param bytes bytes 33 | * @param type type 34 | * @param 泛型 35 | * @return T 36 | */ 37 | T deserialize(byte[] bytes, Type type); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/sh 3 | 4 | ## 0. java 5 | if command -v vfox >/dev/null 2>&1; then 6 | vfox use java@8.0.342+7 7 | else 8 | echo "Warning: vfox command not found, skipping Java version switch" 9 | fi 10 | 11 | ## 1. java version 12 | java -version 13 | printf "\n" 14 | 15 | ## 2. mvn version 16 | mvn -version 17 | printf "\n" 18 | 19 | ## 3. 环境 20 | if [ -z $1 ]; then 21 | profile="release" 22 | else 23 | profile="$1" 24 | fi 25 | printf "profile [%s] \n" "$profile" 26 | 27 | ## 4. modules 28 | modules="mica-mqtt-codec,mica-mqtt-common," 29 | modules="$modules mica-mqtt-client,mica-mqtt-server," 30 | modules="$modules starter/mica-mqtt-client-spring-boot-starter," 31 | modules="$modules starter/mica-mqtt-server-spring-boot-starter," 32 | modules="$modules starter/mica-mqtt-client-solon-plugin," 33 | modules="$modules starter/mica-mqtt-server-solon-plugin," 34 | modules="$modules starter/mica-mqtt-client-jfinal-plugin," 35 | modules="$modules starter/mica-mqtt-server-jfinal-plugin" 36 | printf "modules [%s] \n" "$modules" 37 | 38 | ## 5. deploy 39 | if [ "$profile" = "snapshot" ]; then 40 | mvn clean deploy -U -P!develop,snapshot -pl "$modules" 41 | else 42 | mvn clean deploy -Prelease -pl "$modules" 43 | fi 44 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/codes/MqttReasonCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The vertx Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.codes; 18 | 19 | /** 20 | * Common interface for MQTT messages reason codes enums 21 | * 22 | * @author vertx-mqtt 23 | */ 24 | public interface MqttReasonCode { 25 | 26 | /** 27 | * byteValue 28 | * 29 | * @return byteValue 30 | */ 31 | byte value(); 32 | 33 | /** 34 | * isError 35 | * 36 | * @return boolean 37 | */ 38 | default boolean isError() { 39 | return (value() & 0x80) != 0; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/deserialize/MqttJsonDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.deserialize; 18 | 19 | 20 | import org.tio.utils.json.JsonUtil; 21 | 22 | import java.lang.reflect.Type; 23 | 24 | /** 25 | * mqtt 消息反序列化 26 | * 27 | * @author L.cm 28 | * @author ChangJin Wei(魏昌进) 29 | */ 30 | public class MqttJsonDeserializer implements MqttDeserializer { 31 | 32 | @Override 33 | public T deserialize(byte[] bytes, Type type) { 34 | return JsonUtil.readValue(bytes, type); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/broker/DefaultMqttBrokerDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.broker; 18 | 19 | import org.dromara.mica.mqtt.core.server.dispatcher.AbstractMqttMessageDispatcher; 20 | import org.dromara.mica.mqtt.core.server.model.Message; 21 | 22 | /** 23 | * 默认的消息转发器 24 | * 25 | * @author L.cm 26 | */ 27 | public class DefaultMqttBrokerDispatcher extends AbstractMqttMessageDispatcher { 28 | 29 | @Override 30 | public void sendAll(Message message) { 31 | 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/benchmark/MqttServerBench.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.benchmark; 18 | 19 | import org.dromara.mica.mqtt.core.server.MqttServer; 20 | 21 | /** 22 | * mqtt 服务端测试 23 | * 24 | * @author L.cm 25 | */ 26 | public class MqttServerBench { 27 | 28 | public static void main(String[] args) { 29 | // 设定日志级别为 error 30 | System.setProperty("tinylog.writer.level", "error"); 31 | // 启动 mqtt 服务 32 | MqttServer.create() 33 | .enableMqtt() 34 | .statEnable(false) 35 | .start(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/nginx/MqttServerProxyProtocol.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.nginx; 18 | 19 | 20 | import org.dromara.mica.mqtt.core.server.MqttServer; 21 | 22 | /** 23 | * mqtt 服务端测试 24 | * 25 | * @author L.cm 26 | */ 27 | public class MqttServerProxyProtocol { 28 | 29 | public static void main(String[] args) { 30 | MqttServer.create() 31 | .enableMqtt() 32 | .enableMqttWs() 33 | // 开启代理协议 34 | .proxyProtocolEnable() 35 | .statEnable(false) 36 | .debug() 37 | .start(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/properties/StringProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.properties; 18 | 19 | public final class StringProperty extends MqttProperty { 20 | 21 | public StringProperty(MqttPropertyType propertyType, String value) { 22 | super(propertyType.value(), value); 23 | } 24 | 25 | public StringProperty(int propertyId, String value) { 26 | super(propertyId, value); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "StringProperty(" + propertyId + ", " + value + ')'; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/properties/IntegerProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.properties; 18 | 19 | public final class IntegerProperty extends MqttProperty { 20 | 21 | public IntegerProperty(MqttPropertyType propertyType, Integer value) { 22 | super(propertyType.value(), value); 23 | } 24 | 25 | public IntegerProperty(int propertyId, Integer value) { 26 | super(propertyId, value); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "IntegerProperty(" + propertyId + ", " + value + ')'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/properties/BinaryProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.properties; 18 | 19 | public final class BinaryProperty extends MqttProperty { 20 | 21 | public BinaryProperty(MqttPropertyType propertyType, byte[] value) { 22 | super(propertyType.value(), value); 23 | } 24 | 25 | public BinaryProperty(int propertyId, byte[] value) { 26 | super(propertyId, value); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "BinaryProperty(" + propertyId + ", " + value.length + " bytes)"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/properties/BooleanProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.properties; 18 | 19 | public final class BooleanProperty extends MqttProperty { 20 | 21 | public BooleanProperty(MqttPropertyType propertyType, boolean value) { 22 | this(propertyType.value(), value); 23 | } 24 | 25 | public BooleanProperty(int propertyId, boolean value) { 26 | super(propertyId, value ? 1 : 0); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "BooleanProperty(" + propertyId + ", " + value + ')'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/src/main/java/org/dromara/mica/mqtt/client/solon/event/MqttConnectedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.client.solon.event; 18 | 19 | import lombok.AllArgsConstructor; 20 | import lombok.Data; 21 | import lombok.NoArgsConstructor; 22 | 23 | import java.io.Serializable; 24 | 25 | /** 26 | * mqtt 客户端连接成功事件 27 | * 28 | * @author L.cm 29 | */ 30 | @Data 31 | @NoArgsConstructor 32 | @AllArgsConstructor 33 | public class MqttConnectedEvent implements Serializable { 34 | 35 | /** 36 | * 是否重连 37 | */ 38 | private boolean isReconnect; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/java/org/dromara/mica/mqtt/client/service/HelloInterfaceA.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.client.service; 18 | 19 | import org.dromara.mica.mqtt.core.annotation.MqttClientPublish; 20 | import org.dromara.mica.mqtt.core.annotation.MqttPayload; 21 | import org.dromara.mica.mqtt.spring.client.annotation.MqttClient; 22 | 23 | /** 24 | * @author ChangJin Wei (魏昌进) 25 | */ 26 | @MqttClient 27 | public interface HelloInterfaceA { 28 | 29 | @MqttClientPublish("/test/HelloInterfaceA") 30 | void sayHello(@MqttPayload Object payload); 31 | } 32 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/auth/MqttHttpAuthFilter.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.auth; 2 | 3 | import org.dromara.mica.mqtt.core.server.http.api.code.ResultCode; 4 | import org.dromara.mica.mqtt.core.server.http.api.result.Result; 5 | import org.dromara.mica.mqtt.core.server.http.handler.HttpFilter; 6 | import org.dromara.mica.mqtt.core.server.http.handler.MqttHttpRoutes; 7 | import org.springframework.beans.factory.InitializingBean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.tio.http.common.HttpRequest; 10 | import org.tio.http.common.HttpResponse; 11 | 12 | /** 13 | * 示例自定义 mqtt http 接口认证,请按照自己的需求和业务进行扩展 14 | * 15 | * @author L.cm 16 | */ 17 | @Configuration(proxyBeanMethods = false) 18 | public class MqttHttpAuthFilter implements HttpFilter, InitializingBean { 19 | 20 | @Override 21 | public boolean filter(HttpRequest request) throws Exception { 22 | // 自行实现逻辑 23 | return true; 24 | } 25 | 26 | @Override 27 | public HttpResponse response(HttpRequest request) { 28 | // 认证不通过时的响应 29 | return Result.fail(request, ResultCode.E103); 30 | } 31 | 32 | @Override 33 | public void afterPropertiesSet() throws Exception { 34 | MqttHttpRoutes.addFilter(this); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/java/org/dromara/mica/mqtt/client/service/HelloInterfaceB.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.client.service; 18 | 19 | import org.dromara.mica.mqtt.core.annotation.MqttClientPublish; 20 | import org.dromara.mica.mqtt.core.annotation.MqttPayload; 21 | import org.dromara.mica.mqtt.spring.client.annotation.MqttClient; 22 | 23 | /** 24 | * @author ChangJin Wei (魏昌进) 25 | */ 26 | @MqttClient 27 | public interface HelloInterfaceB { 28 | 29 | @MqttClientPublish("/test/HelloInterfaceB") 30 | void sayHello(@MqttPayload Object payload); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.dromara.mica-mqtt 8 | mica-mqtt 9 | ${revision} 10 | 11 | starter 12 | ${project.artifactId} 13 | pom 14 | 15 | 16 | mica-mqtt-client-spring-boot-starter 17 | mica-mqtt-server-spring-boot-starter 18 | mica-mqtt-client-solon-plugin 19 | mica-mqtt-server-solon-plugin 20 | mica-mqtt-client-jfinal-plugin 21 | mica-mqtt-server-jfinal-plugin 22 | 23 | 24 | 25 | 26 | 27 | org.moditect 28 | moditect-maven-plugin 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/serializer/IMessageSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.serializer; 18 | 19 | import org.dromara.mica.mqtt.core.server.model.Message; 20 | 21 | /** 22 | * 消息编解码 23 | * 24 | * @author L.cm 25 | */ 26 | public interface IMessageSerializer { 27 | 28 | /** 29 | * 消息序列化 30 | * 31 | * @param message Message 32 | * @return byte array 33 | */ 34 | byte[] serialize(Message message); 35 | 36 | /** 37 | * 消息反序列化 38 | * 39 | * @param data byte array 40 | * @return Message 41 | */ 42 | Message deserialize(byte[] data); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/src/main/java/org/dromara/mica/mqtt/client/solon/event/MqttDisconnectEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.client.solon.event; 18 | 19 | import lombok.AllArgsConstructor; 20 | import lombok.Data; 21 | import lombok.NoArgsConstructor; 22 | 23 | import java.io.Serializable; 24 | 25 | /** 26 | * mqtt 客户端断开连接事件 27 | * 28 | * @author L.cm 29 | */ 30 | @Data 31 | @NoArgsConstructor 32 | @AllArgsConstructor 33 | public class MqttDisconnectEvent implements Serializable { 34 | 35 | /** 36 | * 断开原因 37 | */ 38 | String reason; 39 | /** 40 | * 是否删除连接 41 | */ 42 | boolean isRemove; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-jfinal-plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | org.dromara.mica-mqtt 8 | starter 9 | ${revision} 10 | 11 | mica-mqtt-client-jfinal-plugin 12 | ${project.artifactId} 13 | https://mica-mqtt.dreamlu.net/guide/jfinal/client.html 14 | 15 | 16 | 17 | org.dromara.mica-mqtt 18 | mica-mqtt-client 19 | 20 | 21 | com.jfinal 22 | jfinal 23 | provided 24 | 25 | 26 | org.junit.jupiter 27 | junit-jupiter-engine 28 | test 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/support/DefaultMqttServerUniqueIdServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.support; 18 | 19 | import org.dromara.mica.mqtt.core.server.auth.IMqttServerUniqueIdService; 20 | import org.tio.core.ChannelContext; 21 | 22 | /** 23 | * 默认的 mqtt 服务端唯一 id 绑定,使用 clientId 24 | * 25 | * @author L.cm 26 | */ 27 | public class DefaultMqttServerUniqueIdServiceImpl implements IMqttServerUniqueIdService { 28 | 29 | @Override 30 | public String getUniqueId(ChannelContext context, String clientId, String userName, String password) { 31 | return clientId; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-jfinal-plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.dromara.mica-mqtt 8 | starter 9 | ${revision} 10 | 11 | mica-mqtt-server-jfinal-plugin 12 | ${project.artifactId} 13 | https://mica-mqtt.dreamlu.net/guide/jfinal/server.html 14 | 15 | 16 | 17 | org.dromara.mica-mqtt 18 | mica-mqtt-server 19 | 20 | 21 | com.jfinal 22 | jfinal 23 | provided 24 | 25 | 26 | org.junit.jupiter 27 | junit-jupiter-engine 28 | test 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-solon-plugin/src/main/java/org/dromara/mica/mqtt/server/solon/event/MqttClientOfflineEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.server.solon.event; 18 | 19 | import lombok.Data; 20 | 21 | import java.io.Serializable; 22 | 23 | /** 24 | * 客户端断开原因 25 | * 26 | * @author L.cm 27 | */ 28 | @Data 29 | public class MqttClientOfflineEvent implements Serializable { 30 | 31 | /** 32 | * 客户端 Id 33 | */ 34 | private String clientId; 35 | /** 36 | * 用户名 37 | */ 38 | private String username; 39 | /** 40 | * 断开原因 41 | */ 42 | private String reason; 43 | /** 44 | * 时间戳 45 | */ 46 | private long ts; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/broker/DeviceC.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.broker; 18 | 19 | import org.dromara.mica.mqtt.core.client.MqttClient; 20 | 21 | /** 22 | * 设备 C,每 5 秒上报一个数据 23 | * 24 | * @author L.cm 25 | */ 26 | public class DeviceC { 27 | 28 | public static void main(String[] args) { 29 | // 初始化 mqtt 客户端 30 | MqttClient client = MqttClient.create() 31 | .ip("127.0.0.1") 32 | .port(1883) 33 | .username("admin") 34 | .password("123456") 35 | .connectSync(); 36 | 37 | client.schedule(() -> { 38 | client.publish("/a/door/open", null); 39 | 40 | }, 5000); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-spring-boot-starter/src/main/java/org/dromara/mica/mqtt/spring/server/event/MqttClientOfflineEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.spring.server.event; 18 | 19 | import lombok.Data; 20 | 21 | import java.io.Serializable; 22 | 23 | /** 24 | * 客户端断开原因 25 | * 26 | * @author L.cm 27 | */ 28 | @Data 29 | public class MqttClientOfflineEvent implements Serializable { 30 | 31 | /** 32 | * 客户端 Id 33 | */ 34 | private String clientId; 35 | /** 36 | * 用户名 37 | */ 38 | private String username; 39 | /** 40 | * 断开原因 41 | */ 42 | private String reason; 43 | /** 44 | * 时间戳 45 | */ 46 | private long ts; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/src/test/resources/app.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 30036 3 | # mqtt-client 配置 4 | mqtt: 5 | client: 6 | enabled: true # 是否开启客户端,默认:true 7 | ip: 127.0.0.1 # 连接的服务端 ip ,默认:127.0.0.1 8 | port: 18889 # 端口:默认:1883 9 | # clientId: 000001 # 客户端Id(非常重要,一般为设备 sn,不可重复) 10 | # username: mica # 认证的用户名 11 | # password: mica # 认证的密码 12 | # timeout: 5 # 超时时间,单位:秒,默认:5秒 13 | # reconnect: true # 是否重连,默认:true 14 | # re-interval: 5000 # 重连时间,默认 5000 毫秒 15 | # version: mqtt_3_1_1 # mqtt 协议版本,可选 MQTT_3_1、mqtt_3_1_1、mqtt_5,默认:mqtt_3_1_1 16 | # read-buffer-size: 8KB # 接收数据的 buffer size,默认:8k 17 | # max-bytes-in-message: 10MB # 消息解析最大 bytes 长度,默认:10M 18 | # keep-alive-secs: 60 # keep-alive 时间,单位:秒 19 | # clean-session: true # mqtt clean session,默认:true 20 | # ssl: 21 | # enabled: false # 是否开启 ssl 认证,2.1.0 开始支持双向认证 22 | # keystore-path: # 可选参数:ssl 双向认证 keystore 目录,支持 classpath:/ 路径。 23 | # keystore-pass: # 可选参数:ssl 双向认证 keystore 密码 24 | # truststore-path: # 可选参数:ssl 双向认证 truststore 目录,支持 classpath:/ 路径。 25 | # truststore-pass: # 可选参数:ssl 双向认证 truststore 密码 26 | 27 | topic1: /test2/# 28 | -------------------------------------------------------------------------------- /.gitee/ISSUE_TEMPLATE/issue.yml: -------------------------------------------------------------------------------- 1 | name: "问题咨询|反馈" 2 | description: "请尽可能详细的描述问题,提供足够的上下文" 3 | labels: ["question"] 4 | body: 5 | - type: dropdown 6 | id: os 7 | attributes: 8 | label: 操作系统 9 | options: 10 | - "window" 11 | - "linux" 12 | - "MacOS" 13 | validations: 14 | required: true 15 | - type: dropdown 16 | id: version 17 | attributes: 18 | label: mica-mqtt版本 19 | options: 20 | - "2.5.x" 21 | - "2.4.x" 22 | - "老版本建议先升级" 23 | validations: 24 | required: true 25 | - type: dropdown 26 | id: component 27 | attributes: 28 | label: 使用的组件 29 | options: 30 | - "mica-mqtt-client" 31 | - "mica-mqtt-server" 32 | - "mica-mqtt-client-spring-boot-starter" 33 | - "mica-mqtt-server-spring-boot-starter" 34 | - "mica-mqtt-client-solon-plugin" 35 | - "mica-mqtt-server-solon-plugin" 36 | - "mica-mqtt-client-jfinal-plugin" 37 | - "mica-mqtt-server-jfinal-plugin" 38 | - "mica-mqtt-broker 仅供参考" 39 | - "其他" 40 | validations: 41 | required: true 42 | - type: textarea 43 | id: desired-solution 44 | attributes: 45 | label: 问题描述(具体版本号和使用场景,注意:描述不清一句话问题直接关闭) 46 | description: 详细问题,具体版本号和使用场景,提供相应截图和日志 47 | validations: 48 | required: true 49 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/issue.yml: -------------------------------------------------------------------------------- 1 | name: "问题咨询|反馈" 2 | description: "请尽可能详细的描述问题,提供足够的上下文" 3 | labels: ["question"] 4 | body: 5 | - type: dropdown 6 | id: os 7 | attributes: 8 | label: 操作系统 9 | options: 10 | - "window" 11 | - "linux" 12 | - "MacOS" 13 | validations: 14 | required: true 15 | - type: dropdown 16 | id: version 17 | attributes: 18 | label: mica-mqtt版本 19 | options: 20 | - "2.5.x" 21 | - "2.4.x" 22 | - "老版本建议先升级" 23 | validations: 24 | required: true 25 | - type: dropdown 26 | id: component 27 | attributes: 28 | label: 使用的组件 29 | options: 30 | - "mica-mqtt-client" 31 | - "mica-mqtt-server" 32 | - "mica-mqtt-client-spring-boot-starter" 33 | - "mica-mqtt-server-spring-boot-starter" 34 | - "mica-mqtt-client-solon-plugin" 35 | - "mica-mqtt-server-solon-plugin" 36 | - "mica-mqtt-client-jfinal-plugin" 37 | - "mica-mqtt-server-jfinal-plugin" 38 | - "mica-mqtt-broker 仅供参考" 39 | - "其他" 40 | validations: 41 | required: true 42 | - type: textarea 43 | id: desired-solution 44 | attributes: 45 | label: 问题描述(具体版本号和使用场景,注意:描述不清一句话问题直接关闭) 46 | description: 详细问题,具体版本号和使用场景,提供相应截图和日志 47 | validations: 48 | required: true 49 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-solon-plugin-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.dromara.mica-mqtt 8 | example 9 | ${revision} 10 | 11 | mica-mqtt-client-solon-plugin-example 12 | 13 | 14 | 15 | org.noear 16 | solon-web 17 | 18 | 19 | org.dromara.mica-mqtt 20 | mica-mqtt-client-solon-plugin 21 | 22 | 23 | org.noear 24 | solon-logging-simple 25 | 26 | 27 | org.projectlombok 28 | lombok 29 | provided 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/broker/DeviceD.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.broker; 2 | 3 | import org.dromara.mica.mqtt.codec.MqttQoS; 4 | import org.dromara.mica.mqtt.core.annotation.MqttRetain; 5 | import org.dromara.mica.mqtt.core.client.MqttClient; 6 | import org.dromara.mica.mqtt.core.annotation.MqttClientPublish; 7 | import org.dromara.mica.mqtt.core.annotation.MqttPayload; 8 | 9 | /** 10 | * @author ChangJin Wei (魏昌进) 11 | */ 12 | public class DeviceD { 13 | 14 | public static void main(String[] args) { 15 | // 初始化 mqtt 客户端 16 | MqttClient client = MqttClient.create() 17 | .ip("127.0.0.1") 18 | .port(1883) 19 | .username("admin") 20 | .password("123456") 21 | .connectSync(); 22 | 23 | 24 | DoorClient doorClient = client.getInterface(DoorClient.class); 25 | 26 | client.schedule(() -> { 27 | doorClient.sendMessage("open", false); 28 | }, 1000); 29 | } 30 | 31 | public interface DoorClient { 32 | 33 | @MqttClientPublish(value = "/a/door/open", qos = MqttQoS.QOS0) 34 | void sendMessage(@MqttPayload String message, @MqttRetain boolean retain); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/auth/IMqttServerUniqueIdService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.auth; 18 | 19 | import org.tio.core.ChannelContext; 20 | 21 | /** 22 | * mqtt 服务端唯一 id 绑定 23 | * 24 | * @author L.cm 25 | */ 26 | public interface IMqttServerUniqueIdService { 27 | 28 | /** 29 | * 获取 mqtt 唯一id,用来绑定 mqtt 内的 session 等功能 30 | * 31 | * @param context ChannelContext 32 | * @param clientId clientId 33 | * @param userName userName 34 | * @param password password 35 | * @return uniqueId 36 | */ 37 | String getUniqueId(ChannelContext context, String clientId, String userName, String password); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /mica-mqtt-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.dromara.mica-mqtt 8 | mica-mqtt 9 | ${revision} 10 | 11 | mica-mqtt-client 12 | ${project.artifactId} 13 | https://mica-mqtt.dreamlu.net/guide/java/client.html 14 | 15 | 16 | 17 | org.dromara.mica-mqtt 18 | mica-mqtt-common 19 | 20 | 21 | org.junit.jupiter 22 | junit-jupiter-engine 23 | test 24 | 25 | 26 | 27 | 28 | 29 | 30 | org.moditect 31 | moditect-maven-plugin 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /mica-mqtt-codec/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.dromara.mica-mqtt 8 | mica-mqtt 9 | ${revision} 10 | 11 | mica-mqtt-codec 12 | ${project.artifactId} 13 | https://mica-mqtt.dreamlu.net 14 | 15 | 16 | 17 | net.dreamlu 18 | mica-net-core 19 | provided 20 | 21 | 22 | org.junit.jupiter 23 | junit-jupiter-engine 24 | test 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.moditect 32 | moditect-maven-plugin 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/function/ParamValueFunction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.function; 18 | 19 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 20 | import org.tio.core.ChannelContext; 21 | 22 | /** 23 | * 参数值函数 24 | * 25 | * @author L.cm 26 | */ 27 | @FunctionalInterface 28 | public interface ParamValueFunction { 29 | 30 | /** 31 | * 获取值 32 | * 33 | * @param context ChannelContext 34 | * @param topic topic 35 | * @param message message 36 | * @param payload payload 37 | * @return value 38 | */ 39 | Object getValue(ChannelContext context, String topic, MqttPublishMessage message, byte[] payload); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/client/MqttClientConnTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.client; 18 | 19 | import org.dromara.mica.mqtt.codec.codes.MqttConnectReasonCode; 20 | import org.dromara.mica.mqtt.core.client.MqttClient; 21 | 22 | /** 23 | * 客户端测试 24 | * 25 | * @author L.cm 26 | */ 27 | public class MqttClientConnTest { 28 | 29 | public static void main(String[] args) { 30 | // 初始化 mqtt 客户端 31 | MqttConnectReasonCode reasonCode = MqttClient.create() 32 | // .ip("127.0.0.1") 33 | .ip("mqtt.dreamlu.net") 34 | .port(1883) 35 | .username("mica") 36 | .password("mica1") 37 | .connectTest(); 38 | System.out.println(reasonCode); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /mica-mqtt-client/src/main/java/org/dromara/mica/mqtt/core/client/IMqttClientGlobalMessageListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.client; 18 | 19 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 20 | import org.tio.core.ChannelContext; 21 | 22 | /** 23 | * mqtt 全局消息处理 24 | * 25 | * @author L.cm 26 | */ 27 | @FunctionalInterface 28 | public interface IMqttClientGlobalMessageListener { 29 | 30 | /** 31 | * 监听到消息 32 | * 33 | * @param context ChannelContext 34 | * @param topic topic 35 | * @param message MqttPublishMessage 36 | * @param payload payload 37 | */ 38 | void onMessage(ChannelContext context, String topic, MqttPublishMessage message, byte[] payload); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/serializer/JsonMessageSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.serializer; 18 | 19 | import org.dromara.mica.mqtt.core.server.model.Message; 20 | import org.tio.utils.json.JsonUtil; 21 | 22 | /** 23 | * fastjson 序列化 24 | * 25 | * @author L.cm 26 | */ 27 | public class JsonMessageSerializer implements org.dromara.mica.mqtt.core.server.serializer.IMessageSerializer { 28 | 29 | @Override 30 | public byte[] serialize(Message message) { 31 | return JsonUtil.toJsonBytes(message); 32 | } 33 | 34 | @Override 35 | public Message deserialize(byte[] data) { 36 | return JsonUtil.readValue(data, Message.class); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-spring-boot-starter/src/main/java/org/dromara/mica/mqtt/spring/client/event/MqttConnectedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.spring.client.event; 18 | 19 | import lombok.AllArgsConstructor; 20 | import lombok.Data; 21 | import lombok.NoArgsConstructor; 22 | import org.tio.core.ChannelContext; 23 | 24 | import java.io.Serializable; 25 | 26 | /** 27 | * mqtt 客户端连接成功事件 28 | * 29 | * @author L.cm 30 | */ 31 | @Data 32 | @NoArgsConstructor 33 | @AllArgsConstructor 34 | public class MqttConnectedEvent implements Serializable { 35 | 36 | /** 37 | * context 38 | */ 39 | private ChannelContext context; 40 | /** 41 | * 是否重连 42 | */ 43 | private boolean isReconnect; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/http/handler/HttpFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.http.handler; 18 | 19 | import org.tio.http.common.HttpRequest; 20 | import org.tio.http.common.HttpResponse; 21 | 22 | /** 23 | * http 过滤器 24 | * 25 | * @author L.cm 26 | */ 27 | public interface HttpFilter { 28 | 29 | /** 30 | * 处理请求 31 | * 32 | * @param request HttpRequest 33 | * @return 可以为null 34 | * @throws Exception Exception 35 | */ 36 | boolean filter(HttpRequest request) throws Exception; 37 | 38 | /** 39 | * 响应 40 | * 41 | * @param request HttpRequest 42 | * @return HttpResponse 43 | */ 44 | HttpResponse response(HttpRequest request); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/broker/Server.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.broker; 18 | 19 | import org.dromara.mica.mqtt.core.server.MqttServer; 20 | 21 | /** 22 | * 服务端,单纯的做消息转发 23 | * 24 | * @author L.cm 25 | */ 26 | public class Server { 27 | 28 | /** 29 | * 客户端 A 模拟 APP 端订阅 `/a/door/open`, 30 | * 客户端 B 模拟 web 网页端 mqtt.js 订阅 `/a/door/open`, 31 | * Mqtt 服务端实现 `IMqttMessageListener`,将消息转交给 `AbstractMqttMessageDispatcher`(自定义实现)处理。 32 | * 客户端 C 定时上报转态给 `/a/door/open` 33 | * 结果:A 和 B 将收到 C 或 D 发布的消息,并完成相应的效果展示。 34 | */ 35 | public static void main(String[] args) { 36 | // 启动服务,mica-mqtt 1.3.x 已经默认为 broker 模式 37 | MqttServer.create() 38 | .enableMqtt() 39 | .debug() 40 | .start(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/protocol/MqttProtocol.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.protocol; 18 | 19 | /** 20 | * mqtt 协议 21 | * 22 | * @author L.cm 23 | */ 24 | public enum MqttProtocol { 25 | 26 | /** 27 | * mqtt 协议 28 | */ 29 | MQTT(1883), 30 | /** 31 | * mqtt ssl 协议 32 | */ 33 | MQTT_SSL(8883), 34 | /** 35 | * mqtt websocket 子协议 36 | */ 37 | MQTT_WS(8083), 38 | /** 39 | * mqtt websocket ssl 子协议 40 | */ 41 | MQTT_WSS(8084), 42 | /** 43 | * mqtt http api 接口 44 | */ 45 | MQTT_HTTP_API(18083), 46 | ; 47 | 48 | private final int port; 49 | 50 | MqttProtocol(int port) { 51 | this.port = port; 52 | } 53 | 54 | public int getPort() { 55 | return this.port; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-solon-plugin/src/main/java/org/dromara/mica/mqtt/server/solon/event/MqttClientOnlineEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.server.solon.event; 18 | 19 | import lombok.Data; 20 | 21 | import java.io.Serializable; 22 | 23 | /** 24 | * 客户端断开事件 25 | * 26 | * @author L.cm 27 | */ 28 | @Data 29 | public class MqttClientOnlineEvent implements Serializable { 30 | 31 | /** 32 | * 客户端 id 33 | */ 34 | private String clientId; 35 | /** 36 | * 用户名 37 | */ 38 | private String username; 39 | /** 40 | * ip 41 | */ 42 | private String ipAddress; 43 | /** 44 | * 端口 45 | */ 46 | private int port; 47 | /** 48 | * keepalive 49 | */ 50 | private long keepalive; 51 | /** 52 | * 时间戳 53 | */ 54 | private long ts; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /mica-mqtt-client/src/main/java/org/dromara/mica/mqtt/core/client/IMqttClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.client; 18 | 19 | import java.lang.reflect.Proxy; 20 | 21 | /** 22 | * @author ChangJin Wei (魏昌进) 23 | */ 24 | public interface IMqttClient { 25 | 26 | /** 27 | * 获取 mqtt 客户端 28 | * 29 | * @return MqttClient 30 | */ 31 | MqttClient getMqttClient(); 32 | 33 | /** 34 | * 增加一个代理接口方法 35 | * 36 | * @param clientClass 被代理接口 37 | * @param 代理接口的类型 38 | * @return 代理对象 39 | */ 40 | @SuppressWarnings("unchecked") 41 | default T getInterface(Class clientClass) { 42 | return (T) Proxy.newProxyInstance( 43 | clientClass.getClassLoader(), 44 | new Class[]{clientClass}, 45 | new MqttInvocationHandler<>(this) 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/http/api/form/BaseForm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.http.api.form; 18 | 19 | import java.io.Serializable; 20 | 21 | /** 22 | * 基础模型 23 | * 24 | * @author L.cm 25 | */ 26 | public class BaseForm implements Serializable { 27 | 28 | /** 29 | * 主题 Required 30 | */ 31 | private String topic; 32 | /** 33 | * 客户端标识符 Required 34 | */ 35 | private String clientId; 36 | 37 | public String getTopic() { 38 | return topic; 39 | } 40 | 41 | public void setTopic(String topic) { 42 | this.topic = topic; 43 | } 44 | 45 | public String getClientId() { 46 | return clientId; 47 | } 48 | 49 | public void setClientId(String clientId) { 50 | this.clientId = clientId; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-spring-boot-starter/src/main/java/org/dromara/mica/mqtt/spring/client/event/MqttDisconnectEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.spring.client.event; 18 | 19 | import lombok.AllArgsConstructor; 20 | import lombok.Data; 21 | import lombok.NoArgsConstructor; 22 | import org.tio.core.ChannelContext; 23 | 24 | import java.io.Serializable; 25 | 26 | /** 27 | * mqtt 客户端断开连接事件 28 | * 29 | * @author L.cm 30 | */ 31 | @Data 32 | @NoArgsConstructor 33 | @AllArgsConstructor 34 | public class MqttDisconnectEvent implements Serializable { 35 | 36 | /** 37 | * context 38 | */ 39 | private ChannelContext context; 40 | /** 41 | * 断开原因 42 | */ 43 | private String reason; 44 | /** 45 | * 是否删除连接 46 | */ 47 | private boolean isRemove; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-spring-boot-starter/src/main/java/org/dromara/mica/mqtt/spring/server/event/MqttClientOnlineEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.spring.server.event; 18 | 19 | import lombok.Data; 20 | 21 | import java.io.Serializable; 22 | 23 | /** 24 | * 客户端断开事件 25 | * 26 | * @author L.cm 27 | */ 28 | @Data 29 | public class MqttClientOnlineEvent implements Serializable { 30 | 31 | /** 32 | * 客户端 id 33 | */ 34 | private String clientId; 35 | /** 36 | * 用户名 37 | */ 38 | private String username; 39 | /** 40 | * ip 41 | */ 42 | private String ipAddress; 43 | /** 44 | * 端口 45 | */ 46 | private int port; 47 | /** 48 | * keepalive 49 | */ 50 | private long keepalive; 51 | /** 52 | * 时间戳 53 | */ 54 | private long ts; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/event/IMqttMessageListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.event; 18 | 19 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 20 | import org.dromara.mica.mqtt.codec.MqttQoS; 21 | import org.tio.core.ChannelContext; 22 | 23 | /** 24 | * mqtt 消息处理 25 | * 26 | * @author L.cm 27 | */ 28 | @FunctionalInterface 29 | public interface IMqttMessageListener { 30 | 31 | /** 32 | * 监听到消息 33 | * 34 | * @param context ChannelContext 35 | * @param clientId clientId 36 | * @param topic topic 37 | * @param qoS MqttQoS 38 | * @param message Message 39 | */ 40 | void onMessage(ChannelContext context, String clientId, String topic, MqttQoS qoS, MqttPublishMessage message); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/dispatcher/IMqttMessageDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.dispatcher; 18 | 19 | import org.dromara.mica.mqtt.core.server.model.Message; 20 | import org.tio.core.ChannelContext; 21 | 22 | /** 23 | * mqtt 消息调度器 24 | * 25 | * @author L.cm 26 | */ 27 | public interface IMqttMessageDispatcher { 28 | 29 | /** 30 | * 发送消息 31 | * 32 | * @param message 消息 33 | * @return 是否成功 34 | */ 35 | boolean send(Message message); 36 | 37 | /** 38 | * 订阅时下发保留消息,直接发布到订阅的连接 39 | * 40 | * @param context ChannelContext 41 | * @param clientId clientId 42 | * @param retainMessage retainMessage 43 | */ 44 | void sendRetainMessage(ChannelContext context, String clientId, Message retainMessage); 45 | } 46 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/properties/StringPair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.properties; 18 | 19 | public final class StringPair { 20 | public final String key; 21 | public final String value; 22 | 23 | public StringPair(String key, String value) { 24 | this.key = key; 25 | this.value = value; 26 | } 27 | 28 | @Override 29 | public int hashCode() { 30 | return key.hashCode() + 31 * value.hashCode(); 31 | } 32 | 33 | @Override 34 | public boolean equals(Object obj) { 35 | if (this == obj) { 36 | return true; 37 | } 38 | if (obj == null || getClass() != obj.getClass()) { 39 | return false; 40 | } 41 | StringPair that = (StringPair) obj; 42 | 43 | return that.key.equals(this.key) && that.value.equals(this.value); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/func/IMqttFunctionMessageListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.func; 18 | 19 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 20 | import org.dromara.mica.mqtt.codec.MqttQoS; 21 | import org.tio.core.ChannelContext; 22 | 23 | /** 24 | * mqtt 函数监听器 25 | * 26 | * @author L.cm 27 | */ 28 | @FunctionalInterface 29 | public interface IMqttFunctionMessageListener { 30 | 31 | /** 32 | * 监听到消息 33 | * 34 | * @param context ChannelContext 35 | * @param clientId clientId 36 | * @param topic topic 37 | * @param qoS MqttQoS 38 | * @param message Message 39 | */ 40 | void onMessage(ChannelContext context, String clientId, String topic, MqttQoS qoS, MqttPublishMessage message); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/server/solon/listener/MqttConnectOnlineListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.server.solon.listener; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | import org.dromara.mica.mqtt.server.solon.event.MqttClientOnlineEvent; 21 | import org.noear.solon.annotation.Component; 22 | import org.noear.solon.core.event.EventListener; 23 | 24 | /** 25 | * mqtt 连接状态,使用 solon event 方式,性能有损耗 26 | * 27 | * @author L.cm 28 | */ 29 | @Slf4j 30 | @Component 31 | public class MqttConnectOnlineListener implements EventListener { 32 | 33 | @Override 34 | public void onEvent(MqttClientOnlineEvent mqttClientOnlineEvent) throws Throwable { 35 | log.info("MqttClientOnlineEvent:{}", mqttClientOnlineEvent); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/annotation/MqttClientPublish.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.annotation; 18 | 19 | import org.dromara.mica.mqtt.codec.MqttQoS; 20 | 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | /** 27 | * 客户端发布注解 28 | * 29 | * @author ChangJin Wei (魏昌进) 30 | */ 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target(ElementType.METHOD) 33 | public @interface MqttClientPublish { 34 | 35 | /** 36 | * 订阅的 topic 37 | * 38 | * @return topic 39 | */ 40 | String value(); 41 | 42 | /** 43 | * 发布的 qos 44 | * 45 | * @return MqttQoS 46 | */ 47 | MqttQoS qos() default MqttQoS.QOS0; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/server/solon/listener/MqttConnectOfflineListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.server.solon.listener; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | import org.dromara.mica.mqtt.server.solon.event.MqttClientOfflineEvent; 21 | import org.noear.solon.annotation.Component; 22 | import org.noear.solon.core.event.EventListener; 23 | 24 | /** 25 | * mqtt 连接状态,使用 solon event 方式,性能有损耗 26 | * 27 | * @author L.cm 28 | */ 29 | @Slf4j 30 | @Component 31 | public class MqttConnectOfflineListener implements EventListener { 32 | 33 | @Override 34 | public void onEvent(MqttClientOfflineEvent mqttClientOfflineEvent) throws Throwable { 35 | log.info("MqttClientOnlineEvent:{}", mqttClientOfflineEvent); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-spring-boot-starter/src/main/java/org/dromara/mica/mqtt/spring/client/annotation/EnableMqttClients.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.spring.client.annotation; 18 | 19 | import org.dromara.mica.mqtt.spring.client.MqttClientRegistrar; 20 | import org.springframework.context.annotation.Import; 21 | 22 | import java.lang.annotation.Documented; 23 | import java.lang.annotation.ElementType; 24 | import java.lang.annotation.Retention; 25 | import java.lang.annotation.RetentionPolicy; 26 | import java.lang.annotation.Target; 27 | 28 | /** 29 | * @author ChangJin Wei (魏昌进) 30 | */ 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target(ElementType.TYPE) 33 | @Documented 34 | @Import(MqttClientRegistrar.class) 35 | public @interface EnableMqttClients { 36 | 37 | String[] basePackages() default {}; 38 | } 39 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-spring-boot-starter/src/main/java/org/dromara/mica/mqtt/spring/client/annotation/MqttClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.spring.client.annotation; 18 | 19 | import org.dromara.mica.mqtt.spring.client.MqttClientTemplate; 20 | 21 | import java.lang.annotation.Documented; 22 | import java.lang.annotation.ElementType; 23 | import java.lang.annotation.Retention; 24 | import java.lang.annotation.RetentionPolicy; 25 | import java.lang.annotation.Target; 26 | 27 | /** 28 | * @author ChangJin Wei (魏昌进) 29 | */ 30 | @Retention(RetentionPolicy.RUNTIME) 31 | @Target(ElementType.TYPE) 32 | @Documented 33 | public @interface MqttClient { 34 | 35 | /** 36 | * 指定要使用的 MqttClientTemplate Bean 37 | */ 38 | String clientBean() default MqttClientTemplate.DEFAULT_CLIENT_TEMPLATE_BEAN; 39 | } 40 | -------------------------------------------------------------------------------- /mica-mqtt-client/src/main/java/org/dromara/mica/mqtt/core/client/IMqttClientConnectListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.client; 18 | 19 | import org.tio.core.ChannelContext; 20 | 21 | /** 22 | * mqtt 客户端连接监听 23 | * 24 | * @author L.cm 25 | */ 26 | public interface IMqttClientConnectListener { 27 | 28 | /** 29 | * 监听到消息 30 | * 31 | * @param context ChannelContext 32 | * @param isReconnect 是否重连 33 | */ 34 | void onConnected(ChannelContext context, boolean isReconnect); 35 | 36 | /** 37 | * 连接关闭前触发本方法 38 | * 39 | * @param context the ChannelContext 40 | * @param throwable the throwable 有可能为空 41 | * @param remark the remark 有可能为空 42 | * @param isRemove is removed 43 | */ 44 | void onDisconnect(ChannelContext context, Throwable throwable, String remark, boolean isRemove); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/annotation/MqttServerFunction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.annotation; 18 | 19 | import org.dromara.mica.mqtt.core.deserialize.MqttDeserializer; 20 | import org.dromara.mica.mqtt.core.deserialize.MqttJsonDeserializer; 21 | 22 | import java.lang.annotation.*; 23 | 24 | /** 25 | * 服务端函数 26 | * 27 | * @author L.cm 28 | */ 29 | @Documented 30 | @Retention(RetentionPolicy.RUNTIME) 31 | @Target({ElementType.TYPE, ElementType.METHOD}) 32 | public @interface MqttServerFunction { 33 | 34 | /** 35 | * 订阅的 topic filter 36 | * 37 | * @return topic filter 38 | */ 39 | String[] value(); 40 | 41 | /** 42 | * mqtt 消息反序列化 43 | * 44 | * @return 反序列化 45 | */ 46 | Class deserialize() default MqttJsonDeserializer.class; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/src/test/java/org/dromara/mica/mqtt/client/solon/test/listener/MqttClientSubscribeListener.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.solon.test.listener; 2 | 3 | import org.dromara.mica.mqtt.core.annotation.MqttClientSubscribe; 4 | import org.dromara.mica.mqtt.codec.MqttQoS; 5 | import org.noear.solon.annotation.Component; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.nio.charset.StandardCharsets; 10 | 11 | /** 12 | * 客户端消息监听 13 | * 14 | * @author L.cm 15 | */ 16 | @Component 17 | public class MqttClientSubscribeListener { 18 | private static final Logger logger = LoggerFactory.getLogger(MqttClientSubscribeListener.class); 19 | 20 | @MqttClientSubscribe("/test/#") 21 | public void subQos0(String topic, byte[] payload) { 22 | logger.info("topic:{} payload:{}", topic, new String(payload, StandardCharsets.UTF_8)); 23 | } 24 | 25 | @MqttClientSubscribe(value = "/qos1/#", qos = MqttQoS.QOS1) 26 | public void subQos1(String topic, byte[] payload) { 27 | logger.info("topic:{} payload:{}", topic, new String(payload, StandardCharsets.UTF_8)); 28 | } 29 | 30 | @MqttClientSubscribe("/sys/${productKey}/${deviceName}/thing/sub/register") 31 | public void thingSubRegister(String topic, byte[] payload) { 32 | // 1.3.8 开始支持,@MqttClientSubscribe 注解支持 ${} 变量替换,会默认替换成 + 33 | // 注意:mica-mqtt 会先从 Spring boot 配置中替换参数 ${},如果存在配置会优先被替换。 34 | logger.info("topic:{} payload:{}", topic, new String(payload, StandardCharsets.UTF_8)); 35 | } 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/exception/DecoderException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.exception; 18 | 19 | /** 20 | * 解码异常 21 | * 22 | * @author L.cm 23 | */ 24 | public class DecoderException extends RuntimeException { 25 | private static final long serialVersionUID = 1L; 26 | 27 | public DecoderException() { 28 | } 29 | 30 | public DecoderException(String message) { 31 | super(message); 32 | } 33 | 34 | public DecoderException(String message, Throwable cause) { 35 | super(message, cause); 36 | } 37 | 38 | public DecoderException(Throwable cause) { 39 | super(cause); 40 | } 41 | 42 | public DecoderException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 43 | super(message, cause, enableSuppression, writableStackTrace); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/test/java/org/dromara/mica/mqtt/codec/test/MqttCodecUtilTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.test; 18 | 19 | import org.dromara.mica.mqtt.codec.MqttCodecUtil; 20 | import org.junit.jupiter.api.Assertions; 21 | import org.junit.jupiter.api.Test; 22 | 23 | class MqttCodecUtilTest { 24 | 25 | @Test 26 | public void testIsTopicFilter() { 27 | boolean topicFilter1 = MqttCodecUtil.isTopicFilter("/test/123"); 28 | Assertions.assertFalse(topicFilter1); 29 | boolean topicFilter2 = MqttCodecUtil.isTopicFilter("/test/123/"); 30 | Assertions.assertFalse(topicFilter2); 31 | boolean topicFilter3 = MqttCodecUtil.isTopicFilter("/test/+/123"); 32 | Assertions.assertTrue(topicFilter3); 33 | boolean topicFilter4 = MqttCodecUtil.isTopicFilter("/test/#"); 34 | Assertions.assertTrue(topicFilter4); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/event/IMqttConnectStatusListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.event; 18 | 19 | import org.tio.core.ChannelContext; 20 | 21 | /** 22 | * mqtt 链接状态事件 23 | * 24 | * @author L.cm 25 | */ 26 | public interface IMqttConnectStatusListener { 27 | 28 | /** 29 | * 设备上线(连接成功) 30 | * 31 | * @param context ChannelContext 32 | * @param clientId clientId 33 | * @param username username 34 | */ 35 | void online(ChannelContext context, String clientId, String username); 36 | 37 | /** 38 | * 设备离线 39 | * 40 | * @param context ChannelContext 41 | * @param clientId clientId 42 | * @param username username 43 | * @param reason reason 44 | */ 45 | void offline(ChannelContext context, String clientId, String username, String reason); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/MqttConstant.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec; 18 | 19 | /** 20 | * mqtt 常量 21 | * 22 | * @author netty 23 | */ 24 | public interface MqttConstant { 25 | 26 | /** 27 | * mqtt protocol length 28 | */ 29 | int MQTT_PROTOCOL_LENGTH = 2; 30 | 31 | /** 32 | * 默认 最大一次读取的 byte 字节数,默认:8k 33 | */ 34 | int DEFAULT_MAX_READ_BUFFER_SIZE = 8 * 1024; 35 | 36 | /** 37 | * Default max bytes in message,默认:10M 38 | */ 39 | int DEFAULT_MAX_BYTES_IN_MESSAGE = 10 * 1024 * 1024; 40 | 41 | /** 42 | * min client id length 43 | */ 44 | int MIN_CLIENT_ID_LENGTH = 1; 45 | 46 | /** 47 | * Default max client id length,In the mqtt3.1 protocol, 48 | * the default maximum Client Identifier length is 23,设置成 64,减少问题 49 | */ 50 | int DEFAULT_MAX_CLIENT_ID_LENGTH = 64; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/codes/MqttUnSubAckReasonCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The vertx Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.codes; 18 | 19 | /** 20 | * Reason codes for UNSUBACK MQTT message 21 | * 22 | * @author vertx-mqtt 23 | */ 24 | public enum MqttUnSubAckReasonCode implements MqttReasonCode { 25 | 26 | /** 27 | * UnsubAck ReasonCode 28 | */ 29 | SUCCESS((byte) 0x0), 30 | NO_SUBSCRIPTION_EXISTED((byte) 0x11), 31 | UNSPECIFIED_ERROR((byte) 0x80), 32 | IMPLEMENTATION_SPECIFIC_ERROR((byte) 0x83), 33 | NOT_AUTHORIZED((byte) 0x87), 34 | TOPIC_FILTER_INVALID((byte) 0x8F), 35 | PACKET_IDENTIFIER_IN_USE((byte) 0x91); 36 | 37 | private final byte byteValue; 38 | 39 | MqttUnSubAckReasonCode(byte byteValue) { 40 | this.byteValue = byteValue; 41 | } 42 | 43 | @Override 44 | public byte value() { 45 | return byteValue; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/listener/MqttConnectStatusListener1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.server.listener; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | import org.dromara.mica.mqtt.spring.server.event.MqttClientOfflineEvent; 21 | import org.dromara.mica.mqtt.spring.server.event.MqttClientOnlineEvent; 22 | import org.springframework.context.event.EventListener; 23 | 24 | /** 25 | * mqtt 连接状态,使用 spring boot event 方式,性能有损耗 26 | * 27 | * @author L.cm 28 | */ 29 | @Slf4j 30 | //@Service 31 | public class MqttConnectStatusListener1 { 32 | 33 | @EventListener 34 | public void online(MqttClientOnlineEvent event) { 35 | log.info("MqttClientOnlineEvent:{}", event); 36 | } 37 | 38 | @EventListener 39 | public void offline(MqttClientOfflineEvent event) { 40 | log.info("MqttClientOfflineEvent:{}", event); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/broker/DeviceB.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.broker; 18 | 19 | import org.dromara.mica.mqtt.core.client.MqttClient; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | import java.nio.charset.StandardCharsets; 24 | 25 | /** 26 | * 设备 B,这里默认 web 端 27 | * 28 | * @author L.cm 29 | */ 30 | public class DeviceB { 31 | private static final Logger logger = LoggerFactory.getLogger(DeviceB.class); 32 | 33 | public static void main(String[] args) { 34 | // 初始化 mqtt 客户端 35 | MqttClient client = MqttClient.create() 36 | .ip("127.0.0.1") 37 | .port(1883) 38 | .username("admin") 39 | .password("123456") 40 | .connectSync(); 41 | 42 | client.subQos0("/a/door/open", (context, topic, message, payload) -> { 43 | logger.info(topic + '\t' + new String(payload, StandardCharsets.UTF_8)); 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-spring-boot-example/src/main/java/org/dromara/mica/mqtt/client/service/ClientService.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.client.service; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.dromara.mica.mqtt.spring.client.MqttClientTemplate; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Qualifier; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.nio.charset.StandardCharsets; 10 | 11 | /** 12 | * @author wsq 13 | */ 14 | @Slf4j 15 | @Service 16 | public class ClientService { 17 | /** 18 | * 使用 默认的 mqtt client 19 | */ 20 | @Autowired 21 | @Qualifier(MqttClientTemplate.DEFAULT_CLIENT_TEMPLATE_BEAN) 22 | private MqttClientTemplate client; 23 | 24 | @Autowired 25 | private HelloInterfaceA helloInterfaceA; 26 | 27 | @Autowired 28 | private HelloInterfaceB helloInterfaceB; 29 | 30 | public boolean publish(String body) { 31 | client.publish("/test/client", body.getBytes(StandardCharsets.UTF_8)); 32 | return true; 33 | } 34 | 35 | public boolean publishHelloInterfaceA(String body) { 36 | helloInterfaceA.sayHello(body.getBytes(StandardCharsets.UTF_8)); 37 | return true; 38 | } 39 | 40 | public boolean publishHelloInterfaceB(String body) { 41 | helloInterfaceB.sayHello(body.getBytes(StandardCharsets.UTF_8)); 42 | return true; 43 | } 44 | 45 | public boolean sub() { 46 | client.subQos0("/test/#", (context, topic, message, payload) -> { 47 | log.info("{}\t{}", topic, new String(payload, StandardCharsets.UTF_8)); 48 | }); 49 | return true; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/event/IMqttSessionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.event; 18 | 19 | import org.dromara.mica.mqtt.codec.MqttQoS; 20 | import org.tio.core.ChannelContext; 21 | 22 | /** 23 | * mqtt session 事件 24 | * 25 | * @author L.cm 26 | */ 27 | public interface IMqttSessionListener { 28 | 29 | /** 30 | * 订阅 31 | * 32 | * @param context ChannelContext 33 | * @param clientId clientId 34 | * @param topicFilter topicFilter 35 | * @param mqttQoS MqttQoS 36 | */ 37 | void onSubscribed(ChannelContext context, String clientId, String topicFilter, MqttQoS mqttQoS); 38 | 39 | /** 40 | * 取消订阅 41 | * 42 | * @param context ChannelContext 43 | * @param clientId clientId 44 | * @param topicFilter topicFilter 45 | */ 46 | void onUnsubscribed(ChannelContext context, String clientId, String topicFilter); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/broker/DeviceA.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.broker; 18 | 19 | import org.dromara.mica.mqtt.core.client.MqttClient; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | import java.nio.charset.StandardCharsets; 24 | 25 | /** 26 | * 设备 A,这里默认 APP 应用端 27 | * 28 | * @author L.cm 29 | */ 30 | public class DeviceA { 31 | private static final Logger logger = LoggerFactory.getLogger(DeviceA.class); 32 | 33 | public static void main(String[] args) { 34 | // 初始化 mqtt 客户端 35 | MqttClient client = MqttClient.create() 36 | .ip("127.0.0.1") 37 | .port(1883) 38 | .username("admin") 39 | .password("123456") 40 | .connectSync(); 41 | 42 | client.subQos0("/a/door/open", (context, topic, message, payload) -> { 43 | logger.info(topic + '\t' + new String(payload, StandardCharsets.UTF_8)); 44 | }); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/test/java/org/dromara/mica/mqtt/core/common/TopicFilterTypeTest.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.core.common; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | /** 7 | * TopicFilterType 测试 8 | * 9 | * @author L.cm 10 | */ 11 | class TopicFilterTypeTest { 12 | 13 | @Test 14 | void test1() { 15 | String topic1 = "$queue/123"; 16 | TopicFilterType type1 = TopicFilterType.getType(topic1); 17 | Assertions.assertEquals(TopicFilterType.QUEUE, type1); 18 | Assertions.assertTrue(type1.match(topic1, "123")); 19 | Assertions.assertFalse(type1.match(topic1, "/123")); 20 | 21 | String topic2 = "$share/test/123"; 22 | TopicFilterType type2 = TopicFilterType.getType(topic2); 23 | String groupName = TopicFilterType.getShareGroupName(topic2); 24 | Assertions.assertEquals("test", groupName); 25 | Assertions.assertEquals(TopicFilterType.SHARE, type2); 26 | Assertions.assertTrue(type2.match(topic2, "123")); 27 | Assertions.assertFalse(type2.match(topic2, "/123")); 28 | 29 | String topic3 = "$queue//123"; 30 | TopicFilterType type3 = TopicFilterType.getType(topic3); 31 | Assertions.assertEquals(TopicFilterType.QUEUE, type3); 32 | Assertions.assertFalse(type3.match(topic3, "123")); 33 | Assertions.assertTrue(type3.match(topic3, "/123")); 34 | 35 | String topic4 = "$share/test//123"; 36 | TopicFilterType type4 = TopicFilterType.getType(topic4); 37 | Assertions.assertEquals(TopicFilterType.SHARE, type4); 38 | Assertions.assertFalse(type4.match(topic4, "123")); 39 | Assertions.assertTrue(type4.match(topic4, "/123")); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/client/solon/listener/MqttClientConnectedListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.client.solon.listener; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | import org.dromara.mica.mqtt.client.solon.event.MqttConnectedEvent; 21 | import org.dromara.mica.mqtt.core.client.MqttClientCreator; 22 | import org.noear.solon.annotation.Component; 23 | import org.noear.solon.annotation.Inject; 24 | import org.noear.solon.core.event.EventListener; 25 | 26 | /** 27 | * 客户端连接状态监听 28 | * 29 | * @author L.cm 30 | */ 31 | @Slf4j 32 | @Component 33 | public class MqttClientConnectedListener implements EventListener { 34 | @Inject 35 | private MqttClientCreator mqttClientCreator; 36 | 37 | @Override 38 | public void onEvent(MqttConnectedEvent mqttConnectedEvent) throws Throwable { 39 | log.info("MqttConnectedEvent:{}", mqttConnectedEvent); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.dromara.mica-mqtt 8 | starter 9 | ${revision} 10 | 11 | mica-mqtt-client-spring-boot-starter 12 | ${project.artifactId} 13 | https://mica-mqtt.dreamlu.net/guide/spring/client.html 14 | 15 | 16 | 17 | org.dromara.mica-mqtt 18 | mica-mqtt-client 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-autoconfigure 23 | provided 24 | 25 | 26 | org.projectlombok 27 | lombok 28 | provided 29 | 30 | 31 | 32 | net.dreamlu 33 | mica-auto 34 | provided 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/listener/MqttServerMessageListener1.java: -------------------------------------------------------------------------------- 1 | package org.dromara.mica.mqtt.server.listener; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 5 | import org.dromara.mica.mqtt.codec.MqttQoS; 6 | import org.dromara.mica.mqtt.core.server.event.IMqttMessageListener; 7 | import org.dromara.mica.mqtt.spring.server.MqttServerTemplate; 8 | import org.springframework.beans.factory.SmartInitializingSingleton; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.context.ApplicationContext; 11 | import org.tio.core.ChannelContext; 12 | 13 | import java.nio.charset.StandardCharsets; 14 | 15 | /** 16 | * 消息监听器示例1,直接实现 IMqttMessageListener,注意:如果实现了 IMqttMessageListener,MqttServerFunction 注解就不生效了。 17 | * 18 | * @author wsq 19 | */ 20 | @Slf4j 21 | //@Service 22 | public class MqttServerMessageListener1 implements IMqttMessageListener, SmartInitializingSingleton { 23 | @Autowired 24 | private ApplicationContext applicationContext; 25 | private MqttServerTemplate mqttServerTemplate; 26 | 27 | @Override 28 | public void onMessage(ChannelContext context, String clientId, String topic, MqttQoS qos, MqttPublishMessage message) { 29 | log.info("context:{} clientId:{} message:{} payload:{}", context, clientId, message, new String(message.payload(), StandardCharsets.UTF_8)); 30 | } 31 | 32 | @Override 33 | public void afterSingletonsInstantiated() { 34 | // 单利 bean 初始化完成之后从 ApplicationContext 中获取 bean 35 | mqttServerTemplate = applicationContext.getBean(MqttServerTemplate.class); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/listener/MqttConnectStatusListener2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.server.listener; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | import org.dromara.mica.mqtt.core.server.event.IMqttConnectStatusListener; 21 | import org.springframework.stereotype.Service; 22 | import org.tio.core.ChannelContext; 23 | 24 | /** 25 | * mqtt 连接状态 26 | * 27 | * @author L.cm 28 | */ 29 | @Slf4j 30 | @Service 31 | public class MqttConnectStatusListener2 implements IMqttConnectStatusListener { 32 | 33 | @Override 34 | public void online(ChannelContext context, String clientId, String username) { 35 | log.info("Mqtt clientId:{} username:{} online.", clientId, username); 36 | } 37 | 38 | @Override 39 | public void offline(ChannelContext context, String clientId, String username, String reason) { 40 | log.info("Mqtt clientId:{} username:{} offline reason:{}.", clientId, username, reason); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/codes/MqttPubRelReasonCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The vertx Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.codes; 18 | 19 | /** 20 | * Reason codes for PUBREL MQTT message 21 | * 22 | * @author vertx-mqtt 23 | */ 24 | public enum MqttPubRelReasonCode implements MqttReasonCode { 25 | 26 | /** 27 | * PubRel ReasonCode 28 | */ 29 | SUCCESS((byte) 0x0), 30 | PACKET_IDENTIFIER_NOT_FOUND((byte) 0x92); 31 | 32 | private final byte byteValue; 33 | 34 | MqttPubRelReasonCode(byte byteValue) { 35 | this.byteValue = byteValue; 36 | } 37 | 38 | public static MqttPubRelReasonCode valueOf(byte b) { 39 | if (b == SUCCESS.byteValue) { 40 | return SUCCESS; 41 | } else if (b == PACKET_IDENTIFIER_NOT_FOUND.byteValue) { 42 | return PACKET_IDENTIFIER_NOT_FOUND; 43 | } else { 44 | throw new IllegalArgumentException("unknown PUBREL reason code: " + b); 45 | } 46 | } 47 | 48 | @Override 49 | public byte value() { 50 | return byteValue; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/codes/MqttPubCompReasonCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The vertx Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.codes; 18 | 19 | /** 20 | * Reason codes for PUBCOMP MQTT message 21 | * 22 | * @author vertx-mqtt 23 | */ 24 | public enum MqttPubCompReasonCode implements MqttReasonCode { 25 | 26 | /** 27 | * PubComp ReasonCode 28 | */ 29 | SUCCESS((byte) 0x0), 30 | PACKET_IDENTIFIER_NOT_FOUND((byte) 0x92); 31 | 32 | private final byte byteValue; 33 | 34 | MqttPubCompReasonCode(byte byteValue) { 35 | this.byteValue = byteValue; 36 | } 37 | 38 | public static MqttPubCompReasonCode valueOf(byte b) { 39 | if (b == SUCCESS.byteValue) { 40 | return SUCCESS; 41 | } else if (b == PACKET_IDENTIFIER_NOT_FOUND.byteValue) { 42 | return PACKET_IDENTIFIER_NOT_FOUND; 43 | } else { 44 | throw new IllegalArgumentException("unknown PUBCOMP reason code: " + b); 45 | } 46 | } 47 | 48 | @Override 49 | public byte value() { 50 | return byteValue; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/function/ObjectParamValueFunction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.function; 18 | 19 | import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; 20 | import org.dromara.mica.mqtt.core.deserialize.MqttDeserializer; 21 | import org.tio.core.ChannelContext; 22 | 23 | import java.lang.reflect.Type; 24 | 25 | /** 26 | * 需要序列化的对象函数 27 | * 28 | * @author L.cm 29 | */ 30 | public class ObjectParamValueFunction implements ParamValueFunction { 31 | private final MqttDeserializer deserializer; 32 | private final Type parameterType; 33 | 34 | public ObjectParamValueFunction(MqttDeserializer deserializer, Type parameterType) { 35 | this.deserializer = deserializer; 36 | this.parameterType = parameterType; 37 | } 38 | 39 | @Override 40 | public Object getValue(ChannelContext context, String topic, MqttPublishMessage message, byte[] payload) { 41 | return deserializer.deserialize(payload, parameterType); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/codes/ReasonCodeUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The vertx Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.codes; 18 | 19 | /** 20 | * Utilities for MQTT message codes enums 21 | * 22 | * @author vertx-mqtt 23 | */ 24 | public class ReasonCodeUtils { 25 | 26 | protected static void fillValuesByCode(C[] valuesByCode, C[] values) { 27 | for (C code : values) { 28 | final int unsignedByte = code.value() & 0xFF; 29 | valuesByCode[unsignedByte] = code; 30 | } 31 | } 32 | 33 | protected static C codeLoopUp(C[] valuesByCode, byte b, String codeType) { 34 | final int unsignedByte = b & 0xFF; 35 | C reasonCode = null; 36 | try { 37 | reasonCode = valuesByCode[unsignedByte]; 38 | } catch (ArrayIndexOutOfBoundsException ignored) { 39 | // no op 40 | } 41 | if (reasonCode == null) { 42 | throw new IllegalArgumentException("unknown " + codeType + " reason code: " + unsignedByte); 43 | } 44 | return reasonCode; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/server/MqttConnectStatusListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.server; 18 | 19 | import org.dromara.mica.mqtt.core.server.event.IMqttConnectStatusListener; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.tio.core.ChannelContext; 23 | 24 | /** 25 | * mqtt 连接状态 26 | * 27 | * @author L.cm 28 | */ 29 | public class MqttConnectStatusListener implements IMqttConnectStatusListener { 30 | private static final Logger logger = LoggerFactory.getLogger(MqttConnectStatusListener.class); 31 | 32 | @Override 33 | public void online(ChannelContext context, String clientId, String username) { 34 | logger.info("Mqtt clientId:{} username:{} online.", clientId, username); 35 | } 36 | 37 | @Override 38 | public void offline(ChannelContext context, String clientId, String username, String reason) { 39 | logger.info("Mqtt clientId:{} username:{} offline reason:{}.", clientId, username, reason); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.dromara.mica-mqtt 8 | starter 9 | ${revision} 10 | 11 | mica-mqtt-client-solon-plugin 12 | ${project.artifactId} 13 | https://mica-mqtt.dreamlu.net/guide/solon/client.html 14 | 15 | 16 | 17 | org.dromara.mica-mqtt 18 | mica-mqtt-client 19 | 20 | 21 | org.noear 22 | solon 23 | provided 24 | 25 | 26 | org.noear 27 | solon-web 28 | test 29 | 30 | 31 | org.noear 32 | solon-logging-simple 33 | test 34 | 35 | 36 | org.projectlombok 37 | lombok 38 | provided 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/support/DefaultMqttConnectStatusListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.support; 18 | 19 | import org.dromara.mica.mqtt.core.server.event.IMqttConnectStatusListener; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.tio.core.ChannelContext; 23 | 24 | /** 25 | * 默认的链接状态监听 26 | * 27 | * @author L.cm 28 | */ 29 | public class DefaultMqttConnectStatusListener implements IMqttConnectStatusListener { 30 | private static final Logger logger = LoggerFactory.getLogger(DefaultMqttConnectStatusListener.class); 31 | 32 | @Override 33 | public void online(ChannelContext context, String clientId, String username) { 34 | logger.info("Mqtt clientId:{} username:{} online.", clientId, username); 35 | } 36 | 37 | @Override 38 | public void offline(ChannelContext context, String clientId, String username, String reason) { 39 | logger.info("Mqtt clientId:{} username:{} offline reason:{}.", clientId, username, reason); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.github/workflows/publish-snapshot.yml: -------------------------------------------------------------------------------- 1 | name: Publish Snapshot 2 | permissions: 3 | contents: read 4 | on: 5 | push: 6 | branches: [ dev ] 7 | pull_request: 8 | branches: [ dev ] 9 | 10 | jobs: 11 | publish: 12 | runs-on: ubuntu-latest 13 | outputs: 14 | should_continue: ${{ steps.check.outputs.is_snapshot }} 15 | steps: 16 | - uses: actions/checkout@v6 17 | - name: Extract Maven version 18 | id: check 19 | run: | 20 | # 提取 标签中的内容(版本在根项目的 pom.xml 中) 21 | VERSION=$(sed -n 's/\(.*\)<\/revision>/\1/p' pom.xml | tr -d ' ') 22 | echo "Extracted version: $VERSION" 23 | # 检查是否为 SNAPSHOT 24 | if [[ "$VERSION" == *"SNAPSHOT"* ]]; then 25 | echo "is_snapshot=true" >> $GITHUB_OUTPUT 26 | echo "SNAPSHOT version [$VERSION]" 27 | fi 28 | - uses: actions/setup-java@v5 29 | if: ${{ steps.check.outputs.is_snapshot }} 30 | with: 31 | distribution: 'zulu' 32 | java-version: 8 33 | cache: 'maven' 34 | cache-dependency-path: 'pom.xml' 35 | server-id: central 36 | server-username: MAVEN_USERNAME 37 | server-password: MAVEN_PASSWORD 38 | gpg-passphrase: MAVEN_GPG_PASSWORD 39 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 40 | - name: Publish to the Maven Central Repository 41 | if: ${{ steps.check.outputs.is_snapshot }} 42 | run: chmod +x ./deploy.sh && ./deploy.sh snapshot 43 | env: 44 | MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} 45 | MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} 46 | MAVEN_GPG_PASSWORD: ${{ secrets.MAVEN_GPG_PASSWORD }} 47 | -------------------------------------------------------------------------------- /starter/mica-mqtt-client-solon-plugin/src/test/java/org/dromara/mica/mqtt/client/solon/test/listener/MqttClientConnectListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.client.solon.test.listener; 18 | 19 | import org.dromara.mica.mqtt.client.solon.event.MqttConnectedEvent; 20 | import org.dromara.mica.mqtt.core.client.MqttClientCreator; 21 | import org.noear.solon.annotation.Component; 22 | import org.noear.solon.annotation.Inject; 23 | import org.noear.solon.core.event.EventListener; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | /** 28 | * 客户端连接状态监听 29 | * 30 | * @author L.cm 31 | */ 32 | @Component 33 | public class MqttClientConnectListener implements EventListener { 34 | private static final Logger logger = LoggerFactory.getLogger(MqttClientConnectListener.class); 35 | 36 | @Inject 37 | private MqttClientCreator mqttClientCreator; 38 | 39 | @Override 40 | public void onEvent(MqttConnectedEvent mqttConnectedEvent) throws Throwable { 41 | logger.info("MqttConnectedEvent:{}", mqttConnectedEvent); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-solon-plugin-example/src/main/resources/app.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 30303 3 | # solon 配置 4 | solon: 5 | logging: 6 | appender: 7 | console: 8 | level: INFO 9 | # mqtt-client 配置 10 | mqtt: 11 | client: 12 | enabled: true # 是否开启客户端,默认:true 13 | ip: 127.0.0.1 # 连接的服务端 ip ,默认:127.0.0.1 14 | port: 1883 # 端口:默认:1883 15 | name: Mica-Mqtt-Client # 名称,默认:Mica-Mqtt-Client 16 | clientId: 000001 # 客户端Id(非常重要,一般为设备 sn,不可重复) 17 | username: mica # 认证的用户名,注意:2.5.x 开始将 user-name 改成了 username 18 | password: mica # 认证的密码 19 | timeout: 5 # 超时时间,单位:秒,默认:5秒 20 | reconnect: true # 是否重连,默认:true 21 | re-interval: 5000 # 重连时间,默认 5000 毫秒 22 | version: mqtt_3_1_1 # mqtt 协议版本,可选 MQTT_3_1、mqtt_3_1_1、mqtt_5,默认:mqtt_3_1_1 23 | read-buffer-size: 8KB # 接收数据的 buffer size,默认:8k 24 | max-bytes-in-message: 10MB # 消息解析最大 bytes 长度,默认:10M 25 | keep-alive-secs: 60 # keep-alive 时间,单位:秒 26 | heartbeat-mode: LAST_REQ # 心跳模式,支持最后发送或接收心跳时间来计算心跳,默认:最后发送心跳的时间。(2.4.3 开始支持) 27 | heartbeat-timeout-strategy: PING # 心跳超时策略,支持发送 PING 和 CLOSE 断开连接,默认:最大努力发送 PING。(2.4.3 开始支持) 28 | clean-start: true # session 保留 2.5.x 使用 clean-start,老版本用 clean-session,默认:true 29 | ssl: 30 | enabled: false # 是否开启 ssl 认证,2.1.0 开始支持双向认证 31 | keystore-path: # 可选参数:ssl 双向认证 keystore 目录,支持 classpath:/ 路径。 32 | keystore-pass: # 可选参数:ssl 双向认证 keystore 密码 33 | truststore-path: # 可选参数:ssl 双向认证 truststore 目录,支持 classpath:/ 路径。 34 | truststore-pass: # 可选参数:ssl 双向认证 truststore 密码 35 | 36 | topic1: /test/# 37 | -------------------------------------------------------------------------------- /example/mica-mqtt-example/src/main/java/org/dromara/mica/mqtt/client/MqttClientGlobalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.client; 18 | 19 | import org.dromara.mica.mqtt.core.client.MqttClient; 20 | import org.tio.utils.buffer.ByteBufferUtil; 21 | 22 | /** 23 | * 客户端全局订阅测试 24 | * 25 | * @author L.cm 26 | */ 27 | public class MqttClientGlobalTest { 28 | 29 | public static void main(String[] args) { 30 | // 初始化 mqtt 客户端 31 | MqttClient.create() 32 | .ip("127.0.0.1") 33 | .port(1883) 34 | .username("admin") 35 | .password("123456") 36 | // 采用 globalSubscribe,保留 session 停机重启后,可以接受到离线消息,注意:clientId 要不能变化。 37 | .clientId("globalTest") 38 | .cleanStart(false) 39 | // 全局订阅的 topic 40 | .globalSubscribe("/test", "/test/123", "/debug/#") 41 | // 全局监听,也会监听到服务端 http api 订阅的数据 42 | .globalMessageListener((context, topic, message, payload) -> { 43 | System.out.println("topic:\t" + topic); 44 | System.out.println("payload:\t" + ByteBufferUtil.toString(payload)); 45 | }) 46 | // .debug() 47 | .connectSync(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/exception/EncoderException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.exception; 18 | 19 | /** 20 | * An {@link RuntimeException} which is thrown by an encoder. 21 | * 22 | * @author netty 23 | */ 24 | public class EncoderException extends RuntimeException { 25 | 26 | private static final long serialVersionUID = -5086121160476476774L; 27 | 28 | /** 29 | * Creates a new instance. 30 | */ 31 | public EncoderException() { 32 | } 33 | 34 | /** 35 | * Creates a new instance. 36 | * 37 | * @param message message 38 | * @param cause Throwable 39 | */ 40 | public EncoderException(String message, Throwable cause) { 41 | super(message, cause); 42 | } 43 | 44 | /** 45 | * Creates a new instance. 46 | * 47 | * @param message message 48 | */ 49 | public EncoderException(String message) { 50 | super(message); 51 | } 52 | 53 | /** 54 | * Creates a new instance. 55 | * 56 | * @param cause Throwable 57 | */ 58 | public EncoderException(Throwable cause) { 59 | super(cause); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/message/payload/MqttUnsubscribePayload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.message.payload; 18 | 19 | import org.dromara.mica.mqtt.codec.message.MqttUnSubscribeMessage; 20 | 21 | import java.util.Collections; 22 | import java.util.List; 23 | 24 | /** 25 | * Payload of the {@link MqttUnSubscribeMessage} 26 | * 27 | * @author netty 28 | */ 29 | public final class MqttUnsubscribePayload { 30 | private final List topics; 31 | 32 | public MqttUnsubscribePayload(List topics) { 33 | this.topics = Collections.unmodifiableList(topics); 34 | } 35 | 36 | public List topics() { 37 | return topics; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | StringBuilder builder = new StringBuilder("MqttUnsubscribePayload["); 43 | for (String topic : topics) { 44 | builder.append("topicName = ").append(topic).append(", "); 45 | } 46 | if (!topics.isEmpty()) { 47 | builder.setLength(builder.length() - 2); 48 | } 49 | return builder.append(']').toString(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /mica-mqtt-common/src/main/java/org/dromara/mica/mqtt/core/common/TopicFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.common; 18 | 19 | /** 20 | * TopicFilter 21 | * 22 | * @author L.cm 23 | */ 24 | public class TopicFilter { 25 | 26 | /** 27 | * topicFilter 28 | */ 29 | private final String topic; 30 | /** 31 | * topicFilterType 32 | */ 33 | private final TopicFilterType type; 34 | 35 | public TopicFilter(String topicFilter) { 36 | this.topic = topicFilter; 37 | this.type = TopicFilterType.getType(topicFilter); 38 | } 39 | 40 | public String getTopic() { 41 | return topic; 42 | } 43 | 44 | public TopicFilterType getType() { 45 | return type; 46 | } 47 | 48 | /** 49 | * 判断 topicFilter 和 topicName 匹配情况 50 | * 51 | * @param topicName topicName 52 | * @return 是否匹配 53 | */ 54 | public boolean match(String topicName) { 55 | return type.match(this.topic, topicName); 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "TopicFilter{" + 61 | "topic='" + topic + '\'' + 62 | ", type=" + type + 63 | '}'; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/support/DefaultMqttServerAuthHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.support; 18 | 19 | import org.dromara.mica.mqtt.core.server.auth.IMqttServerAuthHandler; 20 | import org.tio.core.ChannelContext; 21 | 22 | import java.util.Objects; 23 | 24 | /** 25 | * 默认的认证处理 26 | * 27 | * @author L.cm 28 | */ 29 | public class DefaultMqttServerAuthHandler implements IMqttServerAuthHandler { 30 | private final String authUsername; 31 | private final String authPassword; 32 | 33 | public DefaultMqttServerAuthHandler(String authUsername, String authPassword) { 34 | this.authUsername = Objects.requireNonNull(authUsername, "Mqtt auth enabled but username is null."); 35 | this.authPassword = Objects.requireNonNull(authPassword, "Mqtt auth enabled but password is null."); 36 | } 37 | 38 | @Override 39 | public boolean authenticate(ChannelContext context, String uniqueId, String clientId, String username, String password) { 40 | return authUsername.equals(username) && authPassword.equals(password); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /starter/mica-mqtt-server-spring-boot-starter/src/main/java/org/dromara/mica/mqtt/spring/server/config/MqttServerMetricsConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). 3 | *

4 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.gnu.org/licenses/lgpl.html 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.spring.server.config; 18 | 19 | import io.micrometer.core.instrument.MeterRegistry; 20 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | 27 | /** 28 | * mica mqtt Metrics 配置 29 | * 30 | * @author L.cm 31 | */ 32 | @Configuration(proxyBeanMethods = false) 33 | @ConditionalOnProperty( 34 | prefix = MqttServerProperties.PREFIX, 35 | name = "enabled", 36 | havingValue = "true" 37 | ) 38 | @ConditionalOnClass(MeterRegistry.class) 39 | @AutoConfigureAfter(MqttServerConfiguration.class) 40 | public class MqttServerMetricsConfiguration { 41 | 42 | @Bean 43 | public MqttServerMetrics micaMqttMetrics() { 44 | return new MqttServerMetrics(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /example/mica-mqtt-client-solon-plugin-example/src/main/java/org/dromara/mica/mqtt/client/solon/listener/MqttClientDisconnectListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.client.solon.listener; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | import org.dromara.mica.mqtt.client.solon.event.MqttDisconnectEvent; 21 | import org.dromara.mica.mqtt.core.client.MqttClientCreator; 22 | import org.noear.solon.annotation.Component; 23 | import org.noear.solon.annotation.Inject; 24 | import org.noear.solon.core.event.EventListener; 25 | 26 | /** 27 | * 客户端连接状态监听 28 | * 29 | * @author L.cm 30 | */ 31 | @Slf4j 32 | @Component 33 | public class MqttClientDisconnectListener implements EventListener { 34 | @Inject 35 | private MqttClientCreator mqttClientCreator; 36 | 37 | @Override 38 | public void onEvent(MqttDisconnectEvent mqttDisconnectEvent) throws Throwable { 39 | log.info("MqttDisconnectEvent:{}", mqttDisconnectEvent); 40 | // 在断线时更新 clientId、username、password,只能改这 3 个,不可调用其他方法。 41 | // mqttClientCreator.clientId("newClient" + System.currentTimeMillis()) 42 | // .username("newUserName") 43 | // .password("newPassword"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/message/MqttConnAckMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.message; 18 | 19 | import org.dromara.mica.mqtt.codec.message.builder.MqttConnAckBuilder; 20 | import org.dromara.mica.mqtt.codec.message.header.MqttConnAckVariableHeader; 21 | import org.dromara.mica.mqtt.codec.message.header.MqttFixedHeader; 22 | 23 | /** 24 | * See MQTTV3.1/connack 25 | * 26 | * @author netty 27 | */ 28 | public final class MqttConnAckMessage extends MqttMessage { 29 | 30 | public MqttConnAckMessage(MqttFixedHeader mqttFixedHeader, MqttConnAckVariableHeader variableHeader) { 31 | super(mqttFixedHeader, variableHeader); 32 | } 33 | 34 | @Override 35 | public MqttConnAckVariableHeader variableHeader() { 36 | return (MqttConnAckVariableHeader) super.variableHeader(); 37 | } 38 | 39 | /** 40 | * Create a builder for a {@link MqttConnAckMessage} 41 | * 42 | * @return a new instance of {@link MqttConnAckBuilder} 43 | */ 44 | public static MqttConnAckBuilder builder() { 45 | return new MqttConnAckBuilder(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /mica-mqtt-codec/src/main/java/org/dromara/mica/mqtt/codec/message/MqttPubAckMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.codec.message; 18 | 19 | import org.dromara.mica.mqtt.codec.message.builder.MqttPubAckBuilder; 20 | import org.dromara.mica.mqtt.codec.message.header.MqttFixedHeader; 21 | import org.dromara.mica.mqtt.codec.message.header.MqttMessageIdVariableHeader; 22 | 23 | /** 24 | * See MQTTV3.1/puback 25 | * 26 | * @author netty 27 | */ 28 | public final class MqttPubAckMessage extends MqttMessage { 29 | 30 | public MqttPubAckMessage(MqttFixedHeader mqttFixedHeader, MqttMessageIdVariableHeader variableHeader) { 31 | super(mqttFixedHeader, variableHeader); 32 | } 33 | 34 | @Override 35 | public MqttMessageIdVariableHeader variableHeader() { 36 | return (MqttMessageIdVariableHeader) super.variableHeader(); 37 | } 38 | 39 | /** 40 | * Create a builder for a {@link MqttPubAckMessage} 41 | * 42 | * @return a new instance of {@link MqttPubAckBuilder} 43 | */ 44 | public static MqttPubAckBuilder builder() { 45 | return new MqttPubAckBuilder(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /mica-mqtt-server/src/main/java/org/dromara/mica/mqtt/core/server/http/api/form/PublishForm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.dromara.mica.mqtt.core.server.http.api.form; 18 | 19 | /** 20 | * 发布的模型 21 | * 22 | * @author L.cm 23 | */ 24 | public class PublishForm extends BaseForm { 25 | 26 | /** 27 | * 消息正文 28 | */ 29 | private String payload; 30 | /** 31 | * 消息正文使用的编码方式,目前仅支持 plain 与 base64 两种 32 | */ 33 | private String encoding; 34 | /** 35 | * QoS 等级 0 36 | */ 37 | private int qos = 0; 38 | /** 39 | * 是否为保留消息 40 | */ 41 | private boolean retain = false; 42 | 43 | public String getPayload() { 44 | return payload; 45 | } 46 | 47 | public void setPayload(String payload) { 48 | this.payload = payload; 49 | } 50 | 51 | public String getEncoding() { 52 | return encoding; 53 | } 54 | 55 | public void setEncoding(String encoding) { 56 | this.encoding = encoding; 57 | } 58 | 59 | public int getQos() { 60 | return qos; 61 | } 62 | 63 | public void setQos(int qos) { 64 | this.qos = qos; 65 | } 66 | 67 | public boolean isRetain() { 68 | return retain; 69 | } 70 | 71 | public void setRetain(boolean retain) { 72 | this.retain = retain; 73 | } 74 | } 75 | --------------------------------------------------------------------------------