first commit

This commit is contained in:
zc
2025-12-08 10:40:43 +08:00
commit 871ae8be0a
410 changed files with 38212 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.dromara.mica-mqtt</groupId>
<artifactId>example</artifactId>
<version>${revision}</version>
</parent>
<artifactId>mica-mqtt-server-solon-plugin-example</artifactId>
<dependencies>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-web</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.mica-mqtt</groupId>
<artifactId>mica-mqtt-server-solon-plugin</artifactId>
</dependency>
<!-- 简单的本地定时任务调度 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-scheduling-simple</artifactId>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-logging-simple</artifactId>
</dependency>
<!-- metrics 指标 开始 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-cloud-metrics</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- metrics 指标 结束 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,19 @@
package org.dromara.mica.mqtt.server.solon;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.scheduling.annotation.EnableScheduling;
/**
* @author wsq
*/
@Configuration
@EnableScheduling
public class MqttServerApplication {
public static void main(String[] args) {
Solon.start(MqttServerApplication.class, args);
}
}

View File

@@ -0,0 +1,22 @@
package org.dromara.mica.mqtt.server.solon.controller;
import org.dromara.mica.mqtt.server.solon.service.ServerService;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Post;
@Mapping("/mqtt/server")
@Controller
public class ServerController {
@Inject
private ServerService service;
@Mapping("publish")
@Post
public boolean publish(String body) {
return service.publish(body);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.mica.mqtt.server.solon.listener;
import lombok.extern.slf4j.Slf4j;
import org.dromara.mica.mqtt.server.solon.event.MqttClientOfflineEvent;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.event.EventListener;
/**
* mqtt 连接状态,使用 solon event 方式,性能有损耗
*
* @author L.cm
*/
@Slf4j
@Component
public class MqttConnectOfflineListener implements EventListener<MqttClientOfflineEvent> {
@Override
public void onEvent(MqttClientOfflineEvent mqttClientOfflineEvent) throws Throwable {
log.info("MqttClientOnlineEvent:{}", mqttClientOfflineEvent);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.net).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.mica.mqtt.server.solon.listener;
import lombok.extern.slf4j.Slf4j;
import org.dromara.mica.mqtt.server.solon.event.MqttClientOnlineEvent;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.event.EventListener;
/**
* mqtt 连接状态,使用 solon event 方式,性能有损耗
*
* @author L.cm
*/
@Slf4j
@Component
public class MqttConnectOnlineListener implements EventListener<MqttClientOnlineEvent> {
@Override
public void onEvent(MqttClientOnlineEvent mqttClientOnlineEvent) throws Throwable {
log.info("MqttClientOnlineEvent:{}", mqttClientOnlineEvent);
}
}

View File

@@ -0,0 +1,25 @@
package org.dromara.mica.mqtt.server.solon.listener;
import lombok.extern.slf4j.Slf4j;
import org.dromara.mica.mqtt.codec.message.MqttPublishMessage;
import org.dromara.mica.mqtt.codec.MqttQoS;
import org.dromara.mica.mqtt.core.server.event.IMqttMessageListener;
import org.tio.core.ChannelContext;
import java.nio.charset.StandardCharsets;
/**
* 消息监听器示例1直接实现 IMqttMessageListener注意如果实现了 IMqttMessageListenerMqttServerFunction 注解就不生效了。
*
* @author wsq
*/
@Slf4j
//@Component
public class MqttServerMessageListener1 implements IMqttMessageListener {
@Override
public void onMessage(ChannelContext context, String clientId, String topic, MqttQoS qos, MqttPublishMessage message) {
log.info("context:{} clientId:{} message:{} payload:{}", context, clientId, message, new String(message.payload(), StandardCharsets.UTF_8));
}
}

View File

@@ -0,0 +1,48 @@
package org.dromara.mica.mqtt.server.solon.listener;
import lombok.extern.slf4j.Slf4j;
import org.dromara.mica.mqtt.codec.message.MqttPublishMessage;
import org.dromara.mica.mqtt.core.annotation.MqttServerFunction;
import org.dromara.mica.mqtt.server.solon.pojo.User;
import org.noear.solon.annotation.Component;
import org.tio.core.ChannelContext;
import org.tio.core.Node;
import java.util.Map;
/**
* 消息监听器示例2MqttServerFunction 注解订阅,注意:如果自行实现了 IMqttMessageListenerMqttServerFunction 注解就不生效了。
*
* @author L.cm
*/
@Slf4j
@Component
public class MqttServerMessageListener2 {
@MqttServerFunction("/test/object")
public void func1(String topic, User<?> user) {
log.info("topic:{} user:{}", topic, user);
}
@MqttServerFunction("/test/client")
public void func1(String topic, byte[] message) {
log.info("topic:{} message:{}", topic, new String(message));
}
/**
* MQTT消息处理函数匹配 mqtt Topic /test/+,如何需要匹配所以消息,请使用通配符 #
*
* @param context ChannelContext可选参数
* @param topic 实际接收到消息的主题名称,可选参数
* @param topicVars topic 中的 ${xxxx} 变量解析v2.5.4支持),可选参数,注意:类型必须为 Map<String, String>
* @param publishMessage 完整的MQTT发布消息对象包含消息头和负载可选参数
* @param message 消息负载内容,以字节数组形式提供,可选参数,也可支持对象形式,默认 json 序列化
*/
@MqttServerFunction("/test/${xxxx}")
public void func3(ChannelContext context, String topic, Map<String, String> topicVars, MqttPublishMessage publishMessage, byte[] message) {
// 获取客户端节点信息
Node clientNode = context.getClientNode();
// 记录接收到的MQTT消息信息
log.info("clientNode:{} topic:{} topicVars:{} publishMessage:{} message:{}", clientNode, topic, topicVars, publishMessage, new String(message));
}
}

View File

@@ -0,0 +1,19 @@
package org.dromara.mica.mqtt.server.solon.pojo;
import lombok.Data;
@Data
public class User<T> {
private String name;
private T girlfriend;
public static User newUser(){
User<User> user1 = new User();
user1.setName("name1");
User<User> user2 = new User();
user2.setName("name2");
user2.setGirlfriend(user1);
return user2;
}
}

View File

@@ -0,0 +1,24 @@
package org.dromara.mica.mqtt.server.solon.service;
import lombok.extern.slf4j.Slf4j;
import org.dromara.mica.mqtt.server.solon.MqttServerTemplate;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.nio.charset.StandardCharsets;
/**
* @author wsq
*/
@Slf4j
@Component
public class ServerService {
@Inject
private MqttServerTemplate server;
public boolean publish(String body) {
boolean result = server.publishAll("/test/123", body.getBytes(StandardCharsets.UTF_8));
log.info("Mqtt publishAll result:{}", result);
return result;
}
}

View File

@@ -0,0 +1,25 @@
package org.dromara.mica.mqtt.server.solon.task;
import org.dromara.mica.mqtt.server.solon.MqttServerTemplate;
import org.dromara.mica.mqtt.server.solon.pojo.User;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.scheduling.annotation.Scheduled;
import java.nio.charset.StandardCharsets;
/**
* @author wsq
*/
@Component
public class PublishTask {
@Inject
private MqttServerTemplate mqttServerTemplate;
@Scheduled(fixedDelay = 1000)
public void publish() {
mqttServerTemplate.publishAll("/test/123", "mica最牛皮".getBytes(StandardCharsets.UTF_8));
mqttServerTemplate.publishAll("/test/object", User.newUser());
}
}

View File

@@ -0,0 +1,54 @@
# solon 配置
solon:
logging:
appender:
console:
level: INFO
# mqtt 服务端配置
mqtt:
server:
enabled: true # 是否开启服务端默认true
name: Mica-Mqtt-Server # 名称默认Mica-Mqtt-Server
heartbeat-timeout: 120000 # 心跳超时,单位毫秒,默认: 1000 * 120
read-buffer-size: 8KB # 接收数据的 buffer size默认8k
max-bytes-in-message: 10MB # 消息解析最大 bytes 长度默认10M
auth:
enable: false # 是否开启 mqtt 认证
username: mica # mqtt 认证用户名
password: mica # mqtt 认证密码
debug: true # 如果开启 prometheus 指标收集建议关闭
stat-enable: true # 开启指标收集debug 和 prometheus 开启时需要打开,默认开启,关闭节省内存
mqtt-listener: # mqtt 监听器
enable: true # 是否开启默认false
# ip: "0.0.0.0" # 服务端 ip 默认为空0.0.0.0,建议不要设置
port: 1883 # 端口默认1883
mqtt-ssl-listener: # mqtt ssl 监听器
enable: false # 是否开启默认false
port: 8883 # 端口默认8883
ssl: # ssl 配置,必须
keystore-path: # 必须参数ssl keystore 目录,支持 classpath:/ 路径。
keystore-pass: # 必选参数ssl keystore 密码
truststore-path: # 可选参数ssl 双向认证 truststore 目录,支持 classpath:/ 路径。
truststore-pass: # 可选参数ssl 双向认证 truststore 密码
client-auth: none # 是否需要客户端认证双向认证默认NONE不需要
ws-listener: # websocket mqtt 监听器
enable: true # 是否开启默认false
port: 8083 # websocket 端口默认8083
wss-listener: # websocket ssl mqtt 监听器
enable: false # 是否开启默认false
port: 8084 # 端口默认8084
ssl: # ssl 配置,必须
keystore-path: # 必须参数ssl keystore 目录,支持 classpath:/ 路径。
keystore-pass: # 必选参数ssl keystore 密码
truststore-path: # 可选参数ssl 双向认证 truststore 目录,支持 classpath:/ 路径。
truststore-pass: # 可选参数ssl 双向认证 truststore 密码
client-auth: none # 是否需要客户端认证双向认证默认NONE不需要
http-listener:
enable: true
port: 18083
basic-auth: # 基础认证
enable: true
username: mica
password: mica
mcp-server: # 大模型 mcp
enable: true