cn.iocoder.boot
diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayConfiguration.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayConfiguration.java
index ef332f1de4..d47e4f9cf6 100644
--- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayConfiguration.java
+++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayConfiguration.java
@@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.iot.gateway.config;
import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
import cn.iocoder.yudao.module.iot.gateway.protocol.coap.IotCoapDownstreamSubscriber;
import cn.iocoder.yudao.module.iot.gateway.protocol.coap.IotCoapUpstreamProtocol;
-import cn.iocoder.yudao.module.iot.gateway.protocol.coap.router.IotCoapAuthHandler;
-import cn.iocoder.yudao.module.iot.gateway.protocol.coap.router.IotCoapUpstreamHandler;
import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxAuthEventProtocol;
import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxDownstreamSubscriber;
import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxUpstreamProtocol;
@@ -207,11 +205,8 @@ public class IotGatewayConfiguration {
public static class CoapProtocolConfiguration {
@Bean
- public IotCoapUpstreamProtocol iotCoapUpstreamProtocol(IotGatewayProperties gatewayProperties,
- IotCoapAuthHandler authHandler,
- IotCoapUpstreamHandler upstreamHandler) {
- return new IotCoapUpstreamProtocol(gatewayProperties.getProtocol().getCoap(),
- authHandler, upstreamHandler);
+ public IotCoapUpstreamProtocol iotCoapUpstreamProtocol(IotGatewayProperties gatewayProperties) {
+ return new IotCoapUpstreamProtocol(gatewayProperties.getProtocol().getCoap());
}
@Bean
diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/IotCoapUpstreamProtocol.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/IotCoapUpstreamProtocol.java
index 2e029e3d63..42f4c8edc2 100644
--- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/IotCoapUpstreamProtocol.java
+++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/IotCoapUpstreamProtocol.java
@@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit;
* 基于 Eclipse Californium 实现,支持:
* 1. 认证:POST /auth
* 2. 属性上报:POST /topic/sys/{productKey}/{deviceName}/thing/property/post
- * 3. 事件上报:POST /topic/sys/{productKey}/{deviceName}/thing/event/{eventId}/post
+ * 3. 事件上报:POST /topic/sys/{productKey}/{deviceName}/thing/event/post
*
* @author 芋道源码
*/
@@ -31,20 +31,13 @@ public class IotCoapUpstreamProtocol {
private final IotGatewayProperties.CoapProperties coapProperties;
- private final IotCoapAuthHandler authHandler;
- private final IotCoapUpstreamHandler upstreamHandler;
-
private CoapServer coapServer;
@Getter
private final String serverId;
- public IotCoapUpstreamProtocol(IotGatewayProperties.CoapProperties coapProperties,
- IotCoapAuthHandler authHandler,
- IotCoapUpstreamHandler upstreamHandler) {
+ public IotCoapUpstreamProtocol(IotGatewayProperties.CoapProperties coapProperties) {
this.coapProperties = coapProperties;
- this.authHandler = authHandler;
- this.upstreamHandler = upstreamHandler;
this.serverId = IotDeviceMessageUtils.generateServerId(coapProperties.getPort());
}
@@ -61,9 +54,11 @@ public class IotCoapUpstreamProtocol {
coapServer = new CoapServer(config);
// 2.1 添加 /auth 认证资源
+ IotCoapAuthHandler authHandler = new IotCoapAuthHandler();
IotCoapAuthResource authResource = new IotCoapAuthResource(this, authHandler);
coapServer.add(authResource);
// 2.2 添加 /topic 根资源(用于上行消息)
+ IotCoapUpstreamHandler upstreamHandler = new IotCoapUpstreamHandler();
IotCoapUpstreamTopicResource topicResource = new IotCoapUpstreamTopicResource(this, upstreamHandler);
coapServer.add(topicResource);
diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/package-info.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/package-info.java
index 8da76ac784..94536a6439 100644
--- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/package-info.java
+++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/package-info.java
@@ -1,14 +1,13 @@
/**
- * IoT 网关 CoAP 协议
- *
- * 基于 Eclipse Californium 实现,支持设备通过 CoAP 协议进行:
- * 1. 属性上报:POST /sys/{productKey}/{deviceName}/thing/property/post
- * 2. 事件上报:POST /sys/{productKey}/{deviceName}/thing/event/{eventId}/post
- *
- * 认证方式:通过 URI Query 参数 token 进行认证
- * 示例:coap://server:5683/sys/pk/dn/thing/property/post?token=xxx
- *
- * @author 芋道源码
+ * CoAP 协议实现包
+ *
+ * 提供基于 Eclipse Californium 的 IoT 设备连接和消息处理功能
+ *
+ * URI 路径:
+ * - 认证:POST /auth
+ * - 属性上报:POST /topic/sys/{productKey}/{deviceName}/thing/property/post
+ * - 事件上报:POST /topic/sys/{productKey}/{deviceName}/thing/event/post
+ *
+ * Token 通过 CoAP Option 2088 携带
*/
-// TODO @AI:参考 /Users/yunai/Java/ruoyi-vue-pro-jdk25/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/package-info.java (现在注释应该有点不太对)
package cn.iocoder.yudao.module.iot.gateway.protocol.coap;
diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/router/IotCoapAuthHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/router/IotCoapAuthHandler.java
index 72bd43f3c6..2348cf990b 100644
--- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/router/IotCoapAuthHandler.java
+++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/router/IotCoapAuthHandler.java
@@ -4,6 +4,7 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi;
@@ -11,19 +12,15 @@ import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceAuthUtils;
import cn.iocoder.yudao.module.iot.gateway.protocol.coap.IotCoapUpstreamProtocol;
+import cn.iocoder.yudao.module.iot.gateway.protocol.coap.util.IotCoapUtils;
import cn.iocoder.yudao.module.iot.gateway.service.auth.IotDeviceTokenService;
import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;
-import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.core.coap.CoAP;
-import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.eclipse.californium.core.server.resources.CoapExchange;
-import org.springframework.stereotype.Component;
import java.util.Map;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
/**
* IoT 网关 CoAP 协议的【认证】处理器
*
@@ -31,53 +28,55 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
*
* @author 芋道源码
*/
-@Component
-@RequiredArgsConstructor
@Slf4j
public class IotCoapAuthHandler {
private final IotDeviceTokenService deviceTokenService;
-
private final IotDeviceCommonApi deviceApi;
-
private final IotDeviceMessageService deviceMessageService;
+ public IotCoapAuthHandler() {
+ this.deviceTokenService = SpringUtil.getBean(IotDeviceTokenService.class);
+ this.deviceApi = SpringUtil.getBean(IotDeviceCommonApi.class);
+ this.deviceMessageService = SpringUtil.getBean(IotDeviceMessageService.class);
+ }
+
/**
* 处理认证请求
*
* @param exchange CoAP 交换对象
* @param protocol 协议对象
*/
+ @SuppressWarnings("unchecked")
public void handle(CoapExchange exchange, IotCoapUpstreamProtocol protocol) {
try {
// 1.1 解析请求体
byte[] payload = exchange.getRequestPayload();
if (payload == null || payload.length == 0) {
- respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "请求体不能为空");
+ IotCoapUtils.respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "请求体不能为空");
return;
}
Map body;
try {
body = JsonUtils.parseObject(new String(payload), Map.class);
} catch (Exception e) {
- respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "请求体 JSON 格式错误");
+ IotCoapUtils.respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "请求体 JSON 格式错误");
return;
}
- // TODO @AI:通过 hutool maputil 去获取,简化下;
// 1.2 解析参数
- String clientId = (String) body.get("clientId");
+ String clientId = MapUtil.getStr(body, "clientId");
if (StrUtil.isEmpty(clientId)) {
- respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "clientId 不能为空");
+ IotCoapUtils.respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "clientId 不能为空");
return;
}
- String username = (String) body.get("username");
+ String username = MapUtil.getStr(body, "username");
if (StrUtil.isEmpty(username)) {
- respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "username 不能为空");
+ IotCoapUtils.respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "username 不能为空");
return;
}
- String password = (String) body.get("password");
+ String password = MapUtil.getStr(body, "password");
if (StrUtil.isEmpty(password)) {
- respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "password 不能为空");
+ IotCoapUtils.respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "password 不能为空");
return;
}
@@ -86,12 +85,12 @@ public class IotCoapAuthHandler {
.setClientId(clientId).setUsername(username).setPassword(password));
if (result.isError()) {
log.warn("[handle][认证失败,clientId: {}, 错误: {}]", clientId, result.getMsg());
- respondError(exchange, CoAP.ResponseCode.UNAUTHORIZED, "认证失败:" + result.getMsg());
+ IotCoapUtils.respondError(exchange, CoAP.ResponseCode.UNAUTHORIZED, "认证失败:" + result.getMsg());
return;
}
if (!BooleanUtil.isTrue(result.getData())) {
log.warn("[handle][认证失败,clientId: {}]", clientId);
- respondError(exchange, CoAP.ResponseCode.UNAUTHORIZED, "认证失败");
+ IotCoapUtils.respondError(exchange, CoAP.ResponseCode.UNAUTHORIZED, "认证失败");
return;
}
// 2.2 生成 Token
@@ -108,31 +107,11 @@ public class IotCoapAuthHandler {
// 4. 返回成功响应
log.info("[handle][认证成功,productKey: {}, deviceName: {}]",
deviceInfo.getProductKey(), deviceInfo.getDeviceName());
- respondSuccess(exchange, MapUtil.of("token", token));
+ IotCoapUtils.respondSuccess(exchange, MapUtil.of("token", token));
} catch (Exception e) {
log.error("[handle][认证处理异常]", e);
- respondError(exchange, CoAP.ResponseCode.INTERNAL_SERVER_ERROR, "服务器内部错误");
+ IotCoapUtils.respondError(exchange, CoAP.ResponseCode.INTERNAL_SERVER_ERROR, "服务器内部错误");
}
}
- // TODO @AI:抽到 coap 的 util 里;
- /**
- * 返回成功响应
- */
- private void respondSuccess(CoapExchange exchange, Object data) {
- CommonResult