This commit is contained in:
parent
bbda3b541d
commit
a7b3fa2ee2
|
|
@ -0,0 +1,202 @@
|
|||
# DJI MQTT 模块使用说明(支持多客户端)
|
||||
|
||||
## 概述
|
||||
|
||||
本模块实现了大疆MQTT消息的接收和处理功能,支持动态创建多个MQTT客户端,每个客户端可以连接到不同的服务器。
|
||||
|
||||
## 核心特性
|
||||
|
||||
✅ **多客户端支持** - 可以同时创建多个MQTT客户端
|
||||
✅ **动态配置** - 每个客户端可以独立配置IP、端口、用户名等
|
||||
✅ **独立消息处理** - 每个客户端有独立的消息处理器
|
||||
✅ **共享订阅可选** - 支持开启/关闭共享订阅
|
||||
✅ **完整数据模型** - 包含所有无人机和机场字段
|
||||
✅ **自动区分设备** - 自动识别无人机和机场数据
|
||||
|
||||
## 架构设计
|
||||
|
||||
```
|
||||
DjiMqttClientManager (管理器)
|
||||
↓
|
||||
DjiMqttClientService (客户端实例)
|
||||
↓
|
||||
DjiMqttMessageHandler (消息处理器)
|
||||
↓
|
||||
IDroneDataCallback / IDockDataCallback (回调接口)
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 注入管理器
|
||||
|
||||
```java
|
||||
@Autowired
|
||||
private DjiMqttClientManager clientManager;
|
||||
```
|
||||
|
||||
### 2. 创建客户端
|
||||
|
||||
```java
|
||||
// 构建配置
|
||||
DjiMqttClientConfig config = DjiMqttClientConfig.builder()
|
||||
.host("mqtt.t-aaron.com") // MQTT服务器地址
|
||||
.port(10883) // 端口
|
||||
.clientId("my_client_1") // 客户端ID(必须唯一)
|
||||
.username("admin") // 用户名
|
||||
.password("admin") // 密码
|
||||
.useSharedSubscription(true) // 是否使用共享订阅
|
||||
.sharedGroupName("dji-group") // 共享订阅组名
|
||||
.build();
|
||||
|
||||
// 创建并连接客户端
|
||||
String clientId = clientManager.createClient(config);
|
||||
```
|
||||
|
||||
### 3. 注册回调
|
||||
|
||||
```java
|
||||
// 获取消息处理器
|
||||
DjiMqttMessageHandler handler = clientManager.getHandler(clientId);
|
||||
|
||||
// 注册无人机数据回调
|
||||
handler.registerDroneDataCallback(droneData -> {
|
||||
System.out.println("无人机SN: " + droneData.getDeviceSn());
|
||||
System.out.println("位置: " + droneData.getLatitude() + ", " + droneData.getLongitude());
|
||||
});
|
||||
|
||||
// 注册机场数据回调
|
||||
handler.registerDockDataCallback(dockData -> {
|
||||
System.out.println("机场SN: " + dockData.getDeviceSn());
|
||||
System.out.println("温度: " + dockData.getTemperature());
|
||||
});
|
||||
```
|
||||
|
||||
## 多客户端示例
|
||||
|
||||
### 场景:同时连接多个MQTT服务器
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class MyMqttService {
|
||||
|
||||
@Autowired
|
||||
private DjiMqttClientManager clientManager;
|
||||
|
||||
public void init() {
|
||||
// 客户端1:连接到服务器A
|
||||
DjiMqttClientConfig config1 = DjiMqttClientConfig.builder()
|
||||
.host("mqtt.server-a.com")
|
||||
.port(10883)
|
||||
.clientId("client_a")
|
||||
.username("admin")
|
||||
.password("admin")
|
||||
.useSharedSubscription(true)
|
||||
.build();
|
||||
|
||||
String clientId1 = clientManager.createClient(config1);
|
||||
DjiMqttMessageHandler handler1 = clientManager.getHandler(clientId1);
|
||||
handler1.registerDroneDataCallback(data -> processServerA(data));
|
||||
|
||||
// 客户端2:连接到服务器B
|
||||
DjiMqttClientConfig config2 = DjiMqttClientConfig.builder()
|
||||
.host("mqtt.server-b.com")
|
||||
.port(1883)
|
||||
.clientId("client_b")
|
||||
.username("user2")
|
||||
.password("pass2")
|
||||
.useSharedSubscription(false)
|
||||
.build();
|
||||
|
||||
String clientId2 = clientManager.createClient(config2);
|
||||
DjiMqttMessageHandler handler2 = clientManager.getHandler(clientId2);
|
||||
handler2.registerDroneDataCallback(data -> processServerB(data));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 管理器API
|
||||
|
||||
### 创建客户端
|
||||
```java
|
||||
String clientId = clientManager.createClient(config);
|
||||
```
|
||||
|
||||
### 获取消息处理器
|
||||
```java
|
||||
DjiMqttMessageHandler handler = clientManager.getHandler(clientId);
|
||||
```
|
||||
|
||||
### 获取客户端
|
||||
```java
|
||||
DjiMqttClientService client = clientManager.getClient(clientId);
|
||||
boolean isConnected = client.isConnected();
|
||||
```
|
||||
|
||||
### 移除客户端
|
||||
```java
|
||||
clientManager.removeClient(clientId);
|
||||
```
|
||||
|
||||
### 断开所有客户端
|
||||
```java
|
||||
clientManager.disconnectAll();
|
||||
```
|
||||
|
||||
### 获取所有客户端ID
|
||||
```java
|
||||
Set<String> clientIds = clientManager.getAllClientIds();
|
||||
```
|
||||
|
||||
## 配置参数说明
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||||
|------|------|------|--------|------|
|
||||
| host | String | 是 | - | MQTT服务器地址 |
|
||||
| port | Integer | 是 | - | MQTT服务器端口 |
|
||||
| clientId | String | 是 | - | 客户端ID(必须唯一) |
|
||||
| username | String | 是 | - | 用户名 |
|
||||
| password | String | 是 | - | 密码 |
|
||||
| connectionTimeout | Integer | 否 | 30 | 连接超时时间(秒) |
|
||||
| keepAliveInterval | Integer | 否 | 60 | 保持连接时间(秒) |
|
||||
| autoReconnect | Boolean | 否 | true | 自动重连 |
|
||||
| cleanSession | Boolean | 否 | false | 清除会话 |
|
||||
| useSharedSubscription | Boolean | 否 | true | 是否使用共享订阅 |
|
||||
| sharedGroupName | String | 否 | dji-group | 共享订阅组名 |
|
||||
|
||||
## 数据模型
|
||||
|
||||
### DroneData(无人机数据)
|
||||
|
||||
包含100+字段,主要分类:
|
||||
- **基础信息**:固件版本、飞行器状态、档位等
|
||||
- **位置信息**:经纬度、高度、Home点等
|
||||
- **姿态信息**:偏航角、横滚角、俯仰角
|
||||
- **速度信息**:水平速度、垂直速度、风速
|
||||
- **电池信息**:电量、剩余飞行时间、电池详情
|
||||
- **相机信息**:拍照录像状态、变焦、红外测温等
|
||||
- **避障信息**:水平/上视/下视避障状态
|
||||
- **保养信息**:保养状态、累计飞行时间/架次
|
||||
|
||||
### DockData(机场数据)
|
||||
|
||||
包含60+字段,主要分类:
|
||||
- **基础信息**:固件版本、机场状态、任务状态
|
||||
- **位置信息**:经纬度、高度、朝向角
|
||||
- **环境信息**:温度、湿度、风速、降雨量
|
||||
- **设备状态**:舱盖状态、飞行器在舱状态、补光灯等
|
||||
- **电池信息**:充电状态、备用电池、电池保养
|
||||
- **网络信息**:网络类型、质量、速率
|
||||
- **图传信息**:4G/SDR链路状态、信号质量
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **clientId必须唯一**:每个MQTT客户端的clientId必须全局唯一
|
||||
2. **部分字段推送**:每次MQTT消息可能只包含部分字段,使用时需要判空
|
||||
3. **原始数据访问**:所有字段都保存在`rawData`中,可以通过Map访问
|
||||
4. **共享订阅**:多实例部署时建议开启共享订阅,避免重复消费
|
||||
5. **独立处理器**:每个客户端有独立的消息处理器,互不影响
|
||||
6. **自动重连**:连接断开后会自动重连(可配置)
|
||||
|
||||
## 完整示例
|
||||
|
||||
参考 `DjiMqttUsageExample.java` 获取完整示例代码。
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.ruoyi.device.domain.impl.djimqtt.config;
|
||||
package com.ruoyi.device.service.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package com.ruoyi.device.service.impl;
|
||||
|
||||
import com.ruoyi.device.domain.impl.djimqtt.callback.IDockDataCallback;
|
||||
import com.ruoyi.device.domain.impl.djimqtt.callback.IDroneDataCallback;
|
||||
import com.ruoyi.device.domain.impl.djimqtt.config.DjiMqttClientConfig;
|
||||
import com.ruoyi.device.service.config.DjiMqttProperties;
|
||||
import com.ruoyi.device.domain.impl.djimqtt.handler.DjiMqttMessageHandler;
|
||||
import com.ruoyi.device.domain.impl.djimqtt.manager.DjiMqttClientManager;
|
||||
import com.ruoyi.device.domain.impl.djimqtt.model.DockData;
|
||||
import com.ruoyi.device.domain.impl.djimqtt.model.DroneData;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class DjiService {
|
||||
|
||||
@Autowired
|
||||
private DjiMqttClientManager clientManager;
|
||||
|
||||
@Autowired
|
||||
private DjiMqttProperties mqttProperties;
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void onApplicationReady() {
|
||||
|
||||
// 从配置文件读取配置
|
||||
DjiMqttClientConfig config = DjiMqttClientConfig.builder()
|
||||
.host(mqttProperties.getHost())
|
||||
.port(mqttProperties.getPort())
|
||||
.clientId(mqttProperties.getClientId())
|
||||
.username(mqttProperties.getUsername())
|
||||
.password(mqttProperties.getPassword())
|
||||
.connectionTimeout(mqttProperties.getConnectionTimeout())
|
||||
.keepAliveInterval(mqttProperties.getKeepAliveInterval())
|
||||
.autoReconnect(mqttProperties.getAutoReconnect())
|
||||
.cleanSession(mqttProperties.getCleanSession())
|
||||
.useSharedSubscription(true)
|
||||
.sharedGroupName("dji-group")
|
||||
.build();
|
||||
|
||||
// 创建客户端
|
||||
String clientId = clientManager.createClient(config);
|
||||
|
||||
// 获取消息处理器
|
||||
DjiMqttMessageHandler handler = clientManager.getHandler(clientId);
|
||||
|
||||
// 注册无人机数据回调
|
||||
handler.registerDroneDataCallback(new IDroneDataCallback() {
|
||||
@Override
|
||||
public void onDroneData(DroneData droneData) {
|
||||
log.info("droneData:{}", droneData);
|
||||
}
|
||||
});
|
||||
|
||||
// 注册机场数据回调
|
||||
handler.registerDockDataCallback(new IDockDataCallback() {
|
||||
@Override
|
||||
public void onDockData(DockData dockData) {
|
||||
log.info("droneData:{}", dockData);
|
||||
}
|
||||
});
|
||||
|
||||
log.info("客户端已创建并注册回调");
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue