Commit 046b2d51e96eb24138ce7b7dcb2f99e8b94c511f
1 parent
1d8ab8ff
feat(iot):【协议改造】tcp 初步改造(70%)
Showing
4 changed files
with
147 additions
and
370 deletions
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/IotHttpProtocol.java
| @@ -42,6 +42,7 @@ public class IotHttpProtocol implements IotProtocol { | @@ -42,6 +42,7 @@ public class IotHttpProtocol implements IotProtocol { | ||
| 42 | /** | 42 | /** |
| 43 | * 运行状态 | 43 | * 运行状态 |
| 44 | */ | 44 | */ |
| 45 | + @Getter | ||
| 45 | private volatile boolean running = false; | 46 | private volatile boolean running = false; |
| 46 | 47 | ||
| 47 | /** | 48 | /** |
| @@ -61,6 +62,8 @@ public class IotHttpProtocol implements IotProtocol { | @@ -61,6 +62,8 @@ public class IotHttpProtocol implements IotProtocol { | ||
| 61 | public IotHttpProtocol(ProtocolInstanceProperties properties, IotMessageBus messageBus) { | 62 | public IotHttpProtocol(ProtocolInstanceProperties properties, IotMessageBus messageBus) { |
| 62 | this.properties = properties; | 63 | this.properties = properties; |
| 63 | this.serverId = IotDeviceMessageUtils.generateServerId(properties.getPort()); | 64 | this.serverId = IotDeviceMessageUtils.generateServerId(properties.getPort()); |
| 65 | + | ||
| 66 | + // 初始化下行消息订阅者 | ||
| 64 | this.downstreamSubscriber = new IotHttpDownstreamSubscriber(this, messageBus); | 67 | this.downstreamSubscriber = new IotHttpDownstreamSubscriber(this, messageBus); |
| 65 | } | 68 | } |
| 66 | 69 | ||
| @@ -169,9 +172,4 @@ public class IotHttpProtocol implements IotProtocol { | @@ -169,9 +172,4 @@ public class IotHttpProtocol implements IotProtocol { | ||
| 169 | log.info("[stop][IoT HTTP 协议 {} 已停止]", getId()); | 172 | log.info("[stop][IoT HTTP 协议 {} 已停止]", getId()); |
| 170 | } | 173 | } |
| 171 | 174 | ||
| 172 | - @Override | ||
| 173 | - public boolean isRunning() { | ||
| 174 | - return running; | ||
| 175 | - } | ||
| 176 | - | ||
| 177 | } | 175 | } |
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/IotTcpProtocol.java
| 1 | package cn.iocoder.yudao.module.iot.gateway.protocol.tcp; | 1 | package cn.iocoder.yudao.module.iot.gateway.protocol.tcp; |
| 2 | 2 | ||
| 3 | -import cn.hutool.extra.spring.SpringUtil; | ||
| 4 | import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum; | 3 | import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum; |
| 5 | import cn.iocoder.yudao.module.iot.core.enums.IotSerializeTypeEnum; | 4 | import cn.iocoder.yudao.module.iot.core.enums.IotSerializeTypeEnum; |
| 6 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; | 5 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; |
| @@ -14,8 +13,6 @@ import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.handler.upstream.IotTcpU | @@ -14,8 +13,6 @@ import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.handler.upstream.IotTcpU | ||
| 14 | import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.manager.IotTcpConnectionManager; | 13 | import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.manager.IotTcpConnectionManager; |
| 15 | import cn.iocoder.yudao.module.iot.gateway.serialize.IotMessageSerializer; | 14 | import cn.iocoder.yudao.module.iot.gateway.serialize.IotMessageSerializer; |
| 16 | import cn.iocoder.yudao.module.iot.gateway.serialize.IotMessageSerializerManager; | 15 | import cn.iocoder.yudao.module.iot.gateway.serialize.IotMessageSerializerManager; |
| 17 | -import cn.iocoder.yudao.module.iot.gateway.service.device.IotDeviceService; | ||
| 18 | -import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService; | ||
| 19 | import io.vertx.core.Vertx; | 16 | import io.vertx.core.Vertx; |
| 20 | import io.vertx.core.net.NetServer; | 17 | import io.vertx.core.net.NetServer; |
| 21 | import io.vertx.core.net.NetServerOptions; | 18 | import io.vertx.core.net.NetServerOptions; |
| @@ -46,6 +43,7 @@ public class IotTcpProtocol implements IotProtocol { | @@ -46,6 +43,7 @@ public class IotTcpProtocol implements IotProtocol { | ||
| 46 | /** | 43 | /** |
| 47 | * 运行状态 | 44 | * 运行状态 |
| 48 | */ | 45 | */ |
| 46 | + @Getter | ||
| 49 | private volatile boolean running = false; | 47 | private volatile boolean running = false; |
| 50 | 48 | ||
| 51 | /** | 49 | /** |
| @@ -72,6 +70,11 @@ public class IotTcpProtocol implements IotProtocol { | @@ -72,6 +70,11 @@ public class IotTcpProtocol implements IotProtocol { | ||
| 72 | */ | 70 | */ |
| 73 | private final IotTcpFrameCodec frameCodec; | 71 | private final IotTcpFrameCodec frameCodec; |
| 74 | 72 | ||
| 73 | + /** | ||
| 74 | + * TCP 连接管理器(每个 Protocol 实例独立) | ||
| 75 | + */ | ||
| 76 | + private final IotTcpConnectionManager connectionManager; | ||
| 77 | + | ||
| 75 | public IotTcpProtocol(ProtocolInstanceProperties properties, IotMessageBus messageBus, | 78 | public IotTcpProtocol(ProtocolInstanceProperties properties, IotMessageBus messageBus, |
| 76 | IotMessageSerializerManager serializerManager) { | 79 | IotMessageSerializerManager serializerManager) { |
| 77 | this.properties = properties; | 80 | this.properties = properties; |
| @@ -83,14 +86,15 @@ public class IotTcpProtocol implements IotProtocol { | @@ -83,14 +86,15 @@ public class IotTcpProtocol implements IotProtocol { | ||
| 83 | serializeType = IotSerializeTypeEnum.JSON; // 默认 JSON | 86 | serializeType = IotSerializeTypeEnum.JSON; // 默认 JSON |
| 84 | } | 87 | } |
| 85 | this.serializer = serializerManager.get(serializeType); | 88 | this.serializer = serializerManager.get(serializeType); |
| 86 | - | ||
| 87 | // 初始化帧编解码器 | 89 | // 初始化帧编解码器 |
| 88 | IotTcpConfig tcpConfig = properties.getTcp(); | 90 | IotTcpConfig tcpConfig = properties.getTcp(); |
| 89 | IotTcpConfig.CodecConfig codecConfig = tcpConfig != null ? tcpConfig.getCodec() : null; | 91 | IotTcpConfig.CodecConfig codecConfig = tcpConfig != null ? tcpConfig.getCodec() : null; |
| 90 | this.frameCodec = IotTcpFrameCodec.create(codecConfig); | 92 | this.frameCodec = IotTcpFrameCodec.create(codecConfig); |
| 91 | 93 | ||
| 94 | + // 初始化连接管理器 | ||
| 95 | + this.connectionManager = new IotTcpConnectionManager(); | ||
| 96 | + | ||
| 92 | // 初始化下行消息订阅者 | 97 | // 初始化下行消息订阅者 |
| 93 | - IotTcpConnectionManager connectionManager = SpringUtil.getBean(IotTcpConnectionManager.class); | ||
| 94 | IotTcpDownstreamHandler downstreamHandler = new IotTcpDownstreamHandler(connectionManager, frameCodec, serializer); | 98 | IotTcpDownstreamHandler downstreamHandler = new IotTcpDownstreamHandler(connectionManager, frameCodec, serializer); |
| 95 | this.downstreamSubscriber = new IotTcpDownstreamSubscriber(this, downstreamHandler, messageBus); | 99 | this.downstreamSubscriber = new IotTcpDownstreamSubscriber(this, downstreamHandler, messageBus); |
| 96 | } | 100 | } |
| @@ -131,12 +135,8 @@ public class IotTcpProtocol implements IotProtocol { | @@ -131,12 +135,8 @@ public class IotTcpProtocol implements IotProtocol { | ||
| 131 | 135 | ||
| 132 | // 1.3 创建服务器并设置连接处理器 | 136 | // 1.3 创建服务器并设置连接处理器 |
| 133 | tcpServer = vertx.createNetServer(options); | 137 | tcpServer = vertx.createNetServer(options); |
| 134 | - IotDeviceService deviceService = SpringUtil.getBean(IotDeviceService.class); | ||
| 135 | - IotDeviceMessageService messageService = SpringUtil.getBean(IotDeviceMessageService.class); | ||
| 136 | - IotTcpConnectionManager connectionManager = SpringUtil.getBean(IotTcpConnectionManager.class); | ||
| 137 | tcpServer.connectHandler(socket -> { | 138 | tcpServer.connectHandler(socket -> { |
| 138 | - IotTcpUpstreamHandler handler = new IotTcpUpstreamHandler(this, messageService, deviceService, | ||
| 139 | - connectionManager, frameCodec, serializer); | 139 | + IotTcpUpstreamHandler handler = new IotTcpUpstreamHandler(serverId, frameCodec, serializer, connectionManager); |
| 140 | handler.handle(socket); | 140 | handler.handle(socket); |
| 141 | }); | 141 | }); |
| 142 | 142 | ||
| @@ -197,9 +197,4 @@ public class IotTcpProtocol implements IotProtocol { | @@ -197,9 +197,4 @@ public class IotTcpProtocol implements IotProtocol { | ||
| 197 | log.info("[stop][IoT TCP 协议 {} 已停止]", getId()); | 197 | log.info("[stop][IoT TCP 协议 {} 已停止]", getId()); |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | - @Override | ||
| 201 | - public boolean isRunning() { | ||
| 202 | - return running; | ||
| 203 | - } | ||
| 204 | - | ||
| 205 | } | 200 | } |
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/handler/upstream/IotTcpUpstreamHandler.java
| 1 | package cn.iocoder.yudao.module.iot.gateway.protocol.tcp.handler.upstream; | 1 | package cn.iocoder.yudao.module.iot.gateway.protocol.tcp.handler.upstream; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.map.MapUtil; | ||
| 4 | -import cn.hutool.core.util.BooleanUtil; | ||
| 5 | import cn.hutool.core.util.IdUtil; | 3 | import cn.hutool.core.util.IdUtil; |
| 6 | import cn.hutool.extra.spring.SpringUtil; | 4 | import cn.hutool.extra.spring.SpringUtil; |
| 7 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| @@ -15,7 +13,6 @@ import cn.iocoder.yudao.module.iot.core.topic.IotDeviceIdentity; | @@ -15,7 +13,6 @@ import cn.iocoder.yudao.module.iot.core.topic.IotDeviceIdentity; | ||
| 15 | import cn.iocoder.yudao.module.iot.core.topic.auth.IotDeviceRegisterReqDTO; | 13 | import cn.iocoder.yudao.module.iot.core.topic.auth.IotDeviceRegisterReqDTO; |
| 16 | import cn.iocoder.yudao.module.iot.core.topic.auth.IotDeviceRegisterRespDTO; | 14 | import cn.iocoder.yudao.module.iot.core.topic.auth.IotDeviceRegisterRespDTO; |
| 17 | import cn.iocoder.yudao.module.iot.core.util.IotDeviceAuthUtils; | 15 | import cn.iocoder.yudao.module.iot.core.util.IotDeviceAuthUtils; |
| 18 | -import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocol; | ||
| 19 | import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.codec.IotTcpFrameCodec; | 16 | import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.codec.IotTcpFrameCodec; |
| 20 | import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.manager.IotTcpConnectionManager; | 17 | import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.manager.IotTcpConnectionManager; |
| 21 | import cn.iocoder.yudao.module.iot.gateway.serialize.IotMessageSerializer; | 18 | import cn.iocoder.yudao.module.iot.gateway.serialize.IotMessageSerializer; |
| @@ -26,8 +23,10 @@ import io.vertx.core.buffer.Buffer; | @@ -26,8 +23,10 @@ import io.vertx.core.buffer.Buffer; | ||
| 26 | import io.vertx.core.net.NetSocket; | 23 | import io.vertx.core.net.NetSocket; |
| 27 | import io.vertx.core.parsetools.RecordParser; | 24 | import io.vertx.core.parsetools.RecordParser; |
| 28 | import lombok.extern.slf4j.Slf4j; | 25 | import lombok.extern.slf4j.Slf4j; |
| 26 | +import org.springframework.util.Assert; | ||
| 29 | 27 | ||
| 30 | -import java.util.Map; | 28 | +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.SUCCESS; |
| 29 | +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.UNAUTHORIZED; | ||
| 31 | 30 | ||
| 32 | /** | 31 | /** |
| 33 | * TCP 上行消息处理器 | 32 | * TCP 上行消息处理器 |
| @@ -39,14 +38,6 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -39,14 +38,6 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 39 | 38 | ||
| 40 | private static final String AUTH_METHOD = "auth"; | 39 | private static final String AUTH_METHOD = "auth"; |
| 41 | 40 | ||
| 42 | - private final IotDeviceMessageService deviceMessageService; | ||
| 43 | - | ||
| 44 | - private final IotDeviceService deviceService; | ||
| 45 | - | ||
| 46 | - private final IotTcpConnectionManager connectionManager; | ||
| 47 | - | ||
| 48 | - private final IotDeviceCommonApi deviceApi; | ||
| 49 | - | ||
| 50 | private final String serverId; | 41 | private final String serverId; |
| 51 | 42 | ||
| 52 | /** | 43 | /** |
| @@ -57,20 +48,30 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -57,20 +48,30 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 57 | * 消息序列化器(处理业务消息序列化/反序列化) | 48 | * 消息序列化器(处理业务消息序列化/反序列化) |
| 58 | */ | 49 | */ |
| 59 | private final IotMessageSerializer serializer; | 50 | private final IotMessageSerializer serializer; |
| 51 | + /** | ||
| 52 | + * TCP 连接管理器(每个 Protocol 实例独立) | ||
| 53 | + */ | ||
| 54 | + private final IotTcpConnectionManager connectionManager; | ||
| 55 | + | ||
| 56 | + // ===================== Spring 依赖(构造时注入) ===================== | ||
| 60 | 57 | ||
| 61 | - public IotTcpUpstreamHandler(IotProtocol protocol, | ||
| 62 | - IotDeviceMessageService deviceMessageService, | ||
| 63 | - IotDeviceService deviceService, | ||
| 64 | - IotTcpConnectionManager connectionManager, | 58 | + private final IotDeviceMessageService deviceMessageService; |
| 59 | + private final IotDeviceService deviceService; | ||
| 60 | + private final IotDeviceCommonApi deviceApi; | ||
| 61 | + | ||
| 62 | + public IotTcpUpstreamHandler(String serverId, | ||
| 65 | IotTcpFrameCodec codec, | 63 | IotTcpFrameCodec codec, |
| 66 | - IotMessageSerializer serializer) { | ||
| 67 | - this.serverId = protocol.getServerId(); | 64 | + IotMessageSerializer serializer, |
| 65 | + IotTcpConnectionManager connectionManager) { | ||
| 66 | + Assert.notNull(codec, "TCP FrameCodec 必须配置"); | ||
| 67 | + Assert.notNull(serializer, "消息序列化器必须配置"); | ||
| 68 | + Assert.notNull(connectionManager, "连接管理器不能为空"); | ||
| 69 | + this.serverId = serverId; | ||
| 68 | this.codec = codec; | 70 | this.codec = codec; |
| 69 | this.serializer = serializer; | 71 | this.serializer = serializer; |
| 70 | this.connectionManager = connectionManager; | 72 | this.connectionManager = connectionManager; |
| 71 | - // TODO @AI:都通过 springutil 获取下; | ||
| 72 | - this.deviceMessageService = deviceMessageService; | ||
| 73 | - this.deviceService = deviceService; | 73 | + this.deviceMessageService = SpringUtil.getBean(IotDeviceMessageService.class); |
| 74 | + this.deviceService = SpringUtil.getBean(IotDeviceService.class); | ||
| 74 | this.deviceApi = SpringUtil.getBean(IotDeviceCommonApi.class); | 75 | this.deviceApi = SpringUtil.getBean(IotDeviceCommonApi.class); |
| 75 | } | 76 | } |
| 76 | 77 | ||
| @@ -79,42 +80,30 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -79,42 +80,30 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 79 | String clientId = IdUtil.simpleUUID(); | 80 | String clientId = IdUtil.simpleUUID(); |
| 80 | log.debug("[handle][设备连接,客户端 ID: {},地址: {}]", clientId, socket.remoteAddress()); | 81 | log.debug("[handle][设备连接,客户端 ID: {},地址: {}]", clientId, socket.remoteAddress()); |
| 81 | 82 | ||
| 82 | - // 设置异常和关闭处理器 | 83 | + // 1. 设置异常和关闭处理器 |
| 83 | socket.exceptionHandler(ex -> { | 84 | socket.exceptionHandler(ex -> { |
| 84 | log.warn("[handle][连接异常,客户端 ID: {},地址: {}]", clientId, socket.remoteAddress()); | 85 | log.warn("[handle][连接异常,客户端 ID: {},地址: {}]", clientId, socket.remoteAddress()); |
| 85 | - cleanupConnection(socket); | 86 | + socket.close(); |
| 86 | }); | 87 | }); |
| 87 | socket.closeHandler(v -> { | 88 | socket.closeHandler(v -> { |
| 88 | log.debug("[handle][连接关闭,客户端 ID: {},地址: {}]", clientId, socket.remoteAddress()); | 89 | log.debug("[handle][连接关闭,客户端 ID: {},地址: {}]", clientId, socket.remoteAddress()); |
| 89 | cleanupConnection(socket); | 90 | cleanupConnection(socket); |
| 90 | }); | 91 | }); |
| 91 | 92 | ||
| 92 | - // 设置消息处理器(带拆包支持) | 93 | + // 2.1 设置消息处理器 |
| 93 | Handler<Buffer> messageHandler = buffer -> { | 94 | Handler<Buffer> messageHandler = buffer -> { |
| 94 | - // TODO @AI:需要跟 AI 讨论。哪些情况关闭;哪些情况,发送异常消息; | ||
| 95 | try { | 95 | try { |
| 96 | processMessage(clientId, buffer, socket); | 96 | processMessage(clientId, buffer, socket); |
| 97 | } catch (Exception e) { | 97 | } catch (Exception e) { |
| 98 | - // TODO @AI:这里能合并到 exceptionHandler 么?还是怎么搞好点; | ||
| 99 | - log.error("[handle][消息解码失败,断开连接,客户端 ID: {},地址: {},错误: {}]", | 98 | + log.error("[handle][消息处理失败,客户端 ID: {},地址: {},错误: {}]", |
| 100 | clientId, socket.remoteAddress(), e.getMessage()); | 99 | clientId, socket.remoteAddress(), e.getMessage()); |
| 101 | - cleanupConnection(socket); | ||
| 102 | socket.close(); | 100 | socket.close(); |
| 103 | } | 101 | } |
| 104 | }; | 102 | }; |
| 105 | - | ||
| 106 | - // 根据是否配置了 FrameCodec 来决定是否使用拆包器 | ||
| 107 | - // TODO @AI:必须配置! | ||
| 108 | - if (codec != null) { | ||
| 109 | - // 使用拆包器处理粘包/拆包 | ||
| 110 | - RecordParser parser = codec.createDecodeParser(messageHandler); | ||
| 111 | - socket.handler(parser); | ||
| 112 | - log.debug("[handle][启用 {} 拆包器,客户端 ID: {}]", codec.getType(), clientId); | ||
| 113 | - } else { | ||
| 114 | - // 未配置拆包器,直接处理原始数据(可能存在粘包问题) | ||
| 115 | - socket.handler(messageHandler); | ||
| 116 | - log.debug("[handle][未配置拆包器,客户端 ID: {}]", clientId); | ||
| 117 | - } | 103 | + // 2.2 使用拆包器处理粘包/拆包 |
| 104 | + RecordParser parser = codec.createDecodeParser(messageHandler); | ||
| 105 | + socket.handler(parser); | ||
| 106 | + log.debug("[handle][启用 {} 拆包器,客户端 ID: {}]", codec.getType(), clientId); | ||
| 118 | } | 107 | } |
| 119 | 108 | ||
| 120 | /** | 109 | /** |
| @@ -123,49 +112,22 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -123,49 +112,22 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 123 | * @param clientId 客户端 ID | 112 | * @param clientId 客户端 ID |
| 124 | * @param buffer 消息 | 113 | * @param buffer 消息 |
| 125 | * @param socket 网络连接 | 114 | * @param socket 网络连接 |
| 126 | - * @throws Exception 消息解码失败时抛出异常 | ||
| 127 | */ | 115 | */ |
| 128 | - private void processMessage(String clientId, Buffer buffer, NetSocket socket) throws Exception { | ||
| 129 | - // 1. 基础检查 | ||
| 130 | - // TODO @AI:不太应该为空?! | ||
| 131 | - if (buffer == null || buffer.length() == 0) { | ||
| 132 | - return; | ||
| 133 | - } | ||
| 134 | - | ||
| 135 | - // 2. 反序列化消息 | ||
| 136 | - IotDeviceMessage message; | ||
| 137 | - try { | ||
| 138 | - message = serializer.deserialize(buffer.getBytes()); | ||
| 139 | - if (message == null) { | ||
| 140 | - throw new IllegalArgumentException("反序列化后消息为空"); | ||
| 141 | - } | ||
| 142 | - } catch (Exception e) { | ||
| 143 | - // TODO @AI:是不是不用 try catch? | ||
| 144 | - throw new Exception("消息反序列化失败: " + e.getMessage(), e); | ||
| 145 | - } | ||
| 146 | - | ||
| 147 | - // 3. 根据消息类型路由处理 | ||
| 148 | - try { | ||
| 149 | - if (AUTH_METHOD.equals(message.getMethod())) { | ||
| 150 | - // 认证请求 | ||
| 151 | - handleAuthenticationRequest(clientId, message, socket); | ||
| 152 | - } else if (IotDeviceMessageMethodEnum.DEVICE_REGISTER.getMethod().equals(message.getMethod())) { | ||
| 153 | - // 设备动态注册请求 | ||
| 154 | - handleRegisterRequest(clientId, message, socket); | ||
| 155 | - } else { | ||
| 156 | - // 业务消息 | ||
| 157 | - handleBusinessRequest(clientId, message, socket); | ||
| 158 | - } | ||
| 159 | - } catch (Exception e) { | ||
| 160 | - // TODO @AI:如果参数不正确,不断开连接; | ||
| 161 | - log.error("[processMessage][处理消息失败,客户端 ID: {},消息方法: {}]", clientId, message.getMethod(), e); | ||
| 162 | - // 发送错误响应,避免客户端一直等待 | ||
| 163 | - // TODO @AI:发送失败,是不是不用 try catch? | ||
| 164 | - try { | ||
| 165 | - sendErrorResponse(socket, message.getRequestId(), "消息处理失败"); | ||
| 166 | - } catch (Exception responseEx) { | ||
| 167 | - log.error("[processMessage][发送错误响应失败,客户端 ID: {}]", clientId, responseEx); | ||
| 168 | - } | 116 | + private void processMessage(String clientId, Buffer buffer, NetSocket socket) { |
| 117 | + // 1. 反序列化消息 | ||
| 118 | + IotDeviceMessage message = serializer.deserialize(buffer.getBytes()); | ||
| 119 | + Assert.notNull(message, "反序列化后消息为空"); | ||
| 120 | + | ||
| 121 | + // 2. 根据消息类型路由处理 | ||
| 122 | + if (AUTH_METHOD.equals(message.getMethod())) { | ||
| 123 | + // 认证请求 | ||
| 124 | + handleAuthenticationRequest(clientId, message, socket); | ||
| 125 | + } else if (IotDeviceMessageMethodEnum.DEVICE_REGISTER.getMethod().equals(message.getMethod())) { | ||
| 126 | + // 设备动态注册请求 | ||
| 127 | + handleRegisterRequest(clientId, message, socket); | ||
| 128 | + } else { | ||
| 129 | + // 业务消息 | ||
| 130 | + handleBusinessRequest(clientId, message, socket); | ||
| 169 | } | 131 | } |
| 170 | } | 132 | } |
| 171 | 133 | ||
| @@ -177,51 +139,33 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -177,51 +139,33 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 177 | * @param socket 网络连接 | 139 | * @param socket 网络连接 |
| 178 | */ | 140 | */ |
| 179 | private void handleAuthenticationRequest(String clientId, IotDeviceMessage message, NetSocket socket) { | 141 | private void handleAuthenticationRequest(String clientId, IotDeviceMessage message, NetSocket socket) { |
| 180 | - try { | ||
| 181 | - // 1.1 解析认证参数 | ||
| 182 | - // TODO @AI:直接 JsonUtils.convertObject(params, IotDeviceAuthReqDTO.class);然后,校验参数,不正确抛出 invalid exception;和 http 那一样; | ||
| 183 | - IotDeviceAuthReqDTO authParams = parseAuthParams(message.getParams()); | ||
| 184 | - if (authParams == null) { | ||
| 185 | - log.warn("[handleAuthenticationRequest][认证参数解析失败,客户端 ID: {}]", clientId); | ||
| 186 | - sendErrorResponse(socket, message.getRequestId(), "认证参数不完整"); | ||
| 187 | - return; | ||
| 188 | - } | ||
| 189 | - // 1.2 执行认证 | ||
| 190 | - if (!validateDeviceAuth(authParams)) { | ||
| 191 | - log.warn("[handleAuthenticationRequest][认证失败,客户端 ID: {},username: {}]", | ||
| 192 | - clientId, authParams.getUsername()); | ||
| 193 | - sendErrorResponse(socket, message.getRequestId(), "认证失败"); | ||
| 194 | - return; | ||
| 195 | - } | ||
| 196 | - | ||
| 197 | - // 2.1 解析设备信息 | ||
| 198 | - IotDeviceIdentity deviceInfo = IotDeviceAuthUtils.parseUsername(authParams.getUsername()); | ||
| 199 | - // TODO @AI:这里就断言 deviceInfo 不为空了?! | ||
| 200 | - if (deviceInfo == null) { | ||
| 201 | - sendErrorResponse(socket, message.getRequestId(), "解析设备信息失败"); | ||
| 202 | - return; | ||
| 203 | - } | ||
| 204 | - // 2.2 获取设备信息 | ||
| 205 | - IotDeviceRespDTO device = deviceService.getDeviceFromCache(deviceInfo.getProductKey(), deviceInfo.getDeviceName()); | ||
| 206 | - // TODO @AI:这里就断言 device 不为空了?! | ||
| 207 | - if (device == null) { | ||
| 208 | - sendErrorResponse(socket, message.getRequestId(), "设备不存在"); | ||
| 209 | - return; | ||
| 210 | - } | ||
| 211 | - | ||
| 212 | - // 3.1 注册连接 | ||
| 213 | - registerConnection(socket, device, clientId); | ||
| 214 | - // 3.2 发送上线消息 | ||
| 215 | - sendOnlineMessage(device); | ||
| 216 | - // 3.3 发送成功响应 | ||
| 217 | - sendSuccessResponse(socket, message.getRequestId(), "认证成功"); | ||
| 218 | - log.info("[handleAuthenticationRequest][认证成功,设备 ID: {},设备名: {}]", | ||
| 219 | - device.getId(), device.getDeviceName()); | ||
| 220 | - } catch (Exception e) { | ||
| 221 | - // TODO @AI:最大化去掉 try catch;(这个方法里的) | ||
| 222 | - log.error("[handleAuthenticationRequest][认证处理异常,客户端 ID: {}]", clientId, e); | ||
| 223 | - sendErrorResponse(socket, message.getRequestId(), "认证处理异常"); | 142 | + // 1. 解析认证参数 |
| 143 | + IotDeviceAuthReqDTO authParams = JsonUtils.convertObject(message.getParams(), IotDeviceAuthReqDTO.class); | ||
| 144 | + Assert.notNull(authParams, "认证参数不能为空"); | ||
| 145 | + Assert.hasText(authParams.getUsername(), "username 不能为空"); | ||
| 146 | + Assert.hasText(authParams.getPassword(), "password 不能为空"); | ||
| 147 | + | ||
| 148 | + // 2.1 执行认证 | ||
| 149 | + CommonResult<Boolean> authResult = deviceApi.authDevice(authParams); | ||
| 150 | + if (authResult.isError()) { | ||
| 151 | + log.warn("[handleAuthenticationRequest][认证失败,客户端 ID: {},username: {}]", clientId, authParams.getUsername()); | ||
| 152 | + sendErrorResponse(socket, message.getRequestId(), AUTH_METHOD, authResult.getCode(), authResult.getMsg()); | ||
| 153 | + return; | ||
| 224 | } | 154 | } |
| 155 | + // 2.2 解析设备信息 | ||
| 156 | + IotDeviceIdentity deviceInfo = IotDeviceAuthUtils.parseUsername(authParams.getUsername()); | ||
| 157 | + Assert.notNull(deviceInfo, "解析设备信息失败"); | ||
| 158 | + // 2.3 获取设备信息 | ||
| 159 | + IotDeviceRespDTO device = deviceService.getDeviceFromCache(deviceInfo.getProductKey(), deviceInfo.getDeviceName()); | ||
| 160 | + Assert.notNull(device, "设备不存在"); | ||
| 161 | + | ||
| 162 | + // 3.1 注册连接 | ||
| 163 | + registerConnection(socket, device, clientId); | ||
| 164 | + // 3.2 发送上线消息 | ||
| 165 | + sendOnlineMessage(device); | ||
| 166 | + // 3.3 发送成功响应 | ||
| 167 | + sendSuccessResponse(socket, message.getRequestId(), AUTH_METHOD, "认证成功"); | ||
| 168 | + log.info("[handleAuthenticationRequest][认证成功,设备 ID: {},设备名: {}]", device.getId(), device.getDeviceName()); | ||
| 225 | } | 169 | } |
| 226 | 170 | ||
| 227 | /** | 171 | /** |
| @@ -233,31 +177,25 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -233,31 +177,25 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 233 | * @see <a href="https://help.aliyun.com/zh/iot/user-guide/unique-certificate-per-product-verification">阿里云 - 一型一密</a> | 177 | * @see <a href="https://help.aliyun.com/zh/iot/user-guide/unique-certificate-per-product-verification">阿里云 - 一型一密</a> |
| 234 | */ | 178 | */ |
| 235 | private void handleRegisterRequest(String clientId, IotDeviceMessage message, NetSocket socket) { | 179 | private void handleRegisterRequest(String clientId, IotDeviceMessage message, NetSocket socket) { |
| 236 | - try { | ||
| 237 | - // 1. 解析注册参数 | ||
| 238 | - IotDeviceRegisterReqDTO params = parseRegisterParams(message.getParams()); | ||
| 239 | - if (params == null) { | ||
| 240 | - log.warn("[handleRegisterRequest][注册参数解析失败,客户端 ID: {}]", clientId); | ||
| 241 | - sendErrorResponse(socket, message.getRequestId(), "注册参数不完整"); | ||
| 242 | - return; | ||
| 243 | - } | ||
| 244 | - | ||
| 245 | - // 2. 调用动态注册 | ||
| 246 | - CommonResult<IotDeviceRegisterRespDTO> result = deviceApi.registerDevice(params); | ||
| 247 | - if (result.isError()) { | ||
| 248 | - log.warn("[handleRegisterRequest][注册失败,客户端 ID: {},错误: {}]", clientId, result.getMsg()); | ||
| 249 | - sendErrorResponse(socket, message.getRequestId(), result.getMsg()); | ||
| 250 | - return; | ||
| 251 | - } | ||
| 252 | - | ||
| 253 | - // 3. 发送成功响应(包含 deviceSecret) | ||
| 254 | - sendRegisterSuccessResponse(socket, message.getRequestId(), result.getData()); | ||
| 255 | - log.info("[handleRegisterRequest][注册成功,客户端 ID: {},设备名: {}]", | ||
| 256 | - clientId, params.getDeviceName()); | ||
| 257 | - } catch (Exception e) { | ||
| 258 | - log.error("[handleRegisterRequest][注册处理异常,客户端 ID: {}]", clientId, e); | ||
| 259 | - sendErrorResponse(socket, message.getRequestId(), "注册处理异常"); | 180 | + // 1. 解析注册参数 |
| 181 | + IotDeviceRegisterReqDTO params = JsonUtils.convertObject(message.getParams(), IotDeviceRegisterReqDTO.class); | ||
| 182 | + Assert.notNull(params, "注册参数不能为空"); | ||
| 183 | + Assert.hasText(params.getProductKey(), "productKey 不能为空"); | ||
| 184 | + Assert.hasText(params.getDeviceName(), "deviceName 不能为空"); | ||
| 185 | + | ||
| 186 | + // 2. 调用动态注册 | ||
| 187 | + CommonResult<IotDeviceRegisterRespDTO> result = deviceApi.registerDevice(params); | ||
| 188 | + if (result.isError()) { | ||
| 189 | + log.warn("[handleRegisterRequest][注册失败,客户端 ID: {},错误: {}]", clientId, result.getMsg()); | ||
| 190 | + sendErrorResponse(socket, message.getRequestId(), IotDeviceMessageMethodEnum.DEVICE_REGISTER.getMethod(), | ||
| 191 | + result.getCode(), result.getMsg()); | ||
| 192 | + return; | ||
| 260 | } | 193 | } |
| 194 | + | ||
| 195 | + // 3. 发送成功响应 | ||
| 196 | + sendSuccessResponse(socket, message.getRequestId(), | ||
| 197 | + IotDeviceMessageMethodEnum.DEVICE_REGISTER.getMethod(), result.getData()); | ||
| 198 | + log.info("[handleRegisterRequest][注册成功,客户端 ID: {},设备名: {}]", clientId, params.getDeviceName()); | ||
| 261 | } | 199 | } |
| 262 | 200 | ||
| 263 | /** | 201 | /** |
| @@ -268,25 +206,19 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -268,25 +206,19 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 268 | * @param socket 网络连接 | 206 | * @param socket 网络连接 |
| 269 | */ | 207 | */ |
| 270 | private void handleBusinessRequest(String clientId, IotDeviceMessage message, NetSocket socket) { | 208 | private void handleBusinessRequest(String clientId, IotDeviceMessage message, NetSocket socket) { |
| 271 | - try { | ||
| 272 | - // 1. 检查认证状态 | ||
| 273 | - if (connectionManager.isNotAuthenticated(socket)) { | ||
| 274 | - log.warn("[handleBusinessRequest][设备未认证,客户端 ID: {}]", clientId); | ||
| 275 | - sendErrorResponse(socket, message.getRequestId(), "请先进行认证"); | ||
| 276 | - return; | ||
| 277 | - } | ||
| 278 | - | ||
| 279 | - // 2. 获取认证信息并处理业务消息 | ||
| 280 | - IotTcpConnectionManager.ConnectionInfo connectionInfo = connectionManager.getConnectionInfo(socket); | ||
| 281 | - | ||
| 282 | - // 3. 发送消息到消息总线 | ||
| 283 | - deviceMessageService.sendDeviceMessage(message, connectionInfo.getProductKey(), | ||
| 284 | - connectionInfo.getDeviceName(), serverId); | ||
| 285 | - log.info("[handleBusinessRequest][发送消息到消息总线,客户端 ID: {},消息: {}", | ||
| 286 | - clientId, message.toString()); | ||
| 287 | - } catch (Exception e) { | ||
| 288 | - log.error("[handleBusinessRequest][业务请求处理异常,客户端 ID: {}]", clientId, e); | 209 | + // 1. 获取认证信息并处理业务消息 |
| 210 | + IotTcpConnectionManager.ConnectionInfo connectionInfo = connectionManager.getConnectionInfo(socket); | ||
| 211 | + if (connectionInfo == null) { | ||
| 212 | + log.error("[handleBusinessRequest][无法获取连接信息,客户端 ID: {}]", clientId); | ||
| 213 | + sendErrorResponse(socket, message.getRequestId(), message.getMethod(), | ||
| 214 | + UNAUTHORIZED.getCode(), "设备未认证,无法处理业务消息"); | ||
| 215 | + return; | ||
| 289 | } | 216 | } |
| 217 | + | ||
| 218 | + // 2. 发送消息到消息总线 | ||
| 219 | + deviceMessageService.sendDeviceMessage(message, connectionInfo.getProductKey(), | ||
| 220 | + connectionInfo.getDeviceName(), serverId); | ||
| 221 | + log.info("[handleBusinessRequest][发送消息到消息总线,客户端 ID: {},消息: {}", clientId, message); | ||
| 290 | } | 222 | } |
| 291 | 223 | ||
| 292 | /** | 224 | /** |
| @@ -302,7 +234,6 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -302,7 +234,6 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 302 | .setProductKey(device.getProductKey()) | 234 | .setProductKey(device.getProductKey()) |
| 303 | .setDeviceName(device.getDeviceName()) | 235 | .setDeviceName(device.getDeviceName()) |
| 304 | .setClientId(clientId); | 236 | .setClientId(clientId); |
| 305 | - // 注册连接 | ||
| 306 | connectionManager.registerConnection(socket, device.getId(), connectionInfo); | 237 | connectionManager.registerConnection(socket, device.getId(), connectionInfo); |
| 307 | } | 238 | } |
| 308 | 239 | ||
| @@ -312,13 +243,9 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -312,13 +243,9 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 312 | * @param device 设备信息 | 243 | * @param device 设备信息 |
| 313 | */ | 244 | */ |
| 314 | private void sendOnlineMessage(IotDeviceRespDTO device) { | 245 | private void sendOnlineMessage(IotDeviceRespDTO device) { |
| 315 | - try { | ||
| 316 | - IotDeviceMessage onlineMessage = IotDeviceMessage.buildStateUpdateOnline(); | ||
| 317 | - deviceMessageService.sendDeviceMessage(onlineMessage, device.getProductKey(), | ||
| 318 | - device.getDeviceName(), serverId); | ||
| 319 | - } catch (Exception e) { | ||
| 320 | - log.error("[sendOnlineMessage][发送上线消息失败,设备: {}]", device.getDeviceName(), e); | ||
| 321 | - } | 246 | + IotDeviceMessage onlineMessage = IotDeviceMessage.buildStateUpdateOnline(); |
| 247 | + deviceMessageService.sendDeviceMessage(onlineMessage, device.getProductKey(), | ||
| 248 | + device.getDeviceName(), serverId); | ||
| 322 | } | 249 | } |
| 323 | 250 | ||
| 324 | /** | 251 | /** |
| @@ -327,182 +254,57 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | @@ -327,182 +254,57 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> { | ||
| 327 | * @param socket 网络连接 | 254 | * @param socket 网络连接 |
| 328 | */ | 255 | */ |
| 329 | private void cleanupConnection(NetSocket socket) { | 256 | private void cleanupConnection(NetSocket socket) { |
| 330 | - try { | ||
| 331 | - // 1. 发送离线消息(如果已认证) | ||
| 332 | - IotTcpConnectionManager.ConnectionInfo connectionInfo = connectionManager.getConnectionInfo(socket); | ||
| 333 | - if (connectionInfo != null) { | ||
| 334 | - IotDeviceMessage offlineMessage = IotDeviceMessage.buildStateOffline(); | ||
| 335 | - deviceMessageService.sendDeviceMessage(offlineMessage, connectionInfo.getProductKey(), | ||
| 336 | - connectionInfo.getDeviceName(), serverId); | ||
| 337 | - } | ||
| 338 | - | ||
| 339 | - // 2. 注销连接 | ||
| 340 | - connectionManager.unregisterConnection(socket); | ||
| 341 | - } catch (Exception e) { | ||
| 342 | - log.error("[cleanupConnection][清理连接失败]", e); | ||
| 343 | - } | ||
| 344 | - } | ||
| 345 | - | ||
| 346 | - /** | ||
| 347 | - * 发送响应消息 | ||
| 348 | - * | ||
| 349 | - * @param socket 网络连接 | ||
| 350 | - * @param success 是否成功 | ||
| 351 | - * @param message 消息 | ||
| 352 | - * @param requestId 请求 ID | ||
| 353 | - */ | ||
| 354 | - private void sendResponse(NetSocket socket, boolean success, String message, String requestId) { | ||
| 355 | - try { | ||
| 356 | - // TODO @AI:是不是不用 | ||
| 357 | - Object responseData = MapUtil.builder() | ||
| 358 | - .put("success", success) | ||
| 359 | - .put("message", message) | ||
| 360 | - .build(); | ||
| 361 | - | ||
| 362 | - int code = success ? 0 : 401; | ||
| 363 | - IotDeviceMessage responseMessage = IotDeviceMessage.replyOf(requestId, AUTH_METHOD, responseData, | ||
| 364 | - code, message); | ||
| 365 | - | ||
| 366 | - // 序列化 + 帧编码 | ||
| 367 | - byte[] serializedData = serializer.serialize(responseMessage); | ||
| 368 | - Buffer frameData = codec.encode(serializedData); | ||
| 369 | - socket.write(frameData); | ||
| 370 | - | ||
| 371 | - } catch (Exception e) { | ||
| 372 | - log.error("[sendResponse][发送响应失败,requestId: {}]", requestId, e); | 257 | + // 1. 发送离线消息 |
| 258 | + IotTcpConnectionManager.ConnectionInfo connectionInfo = connectionManager.getConnectionInfo(socket); | ||
| 259 | + if (connectionInfo != null) { | ||
| 260 | + IotDeviceMessage offlineMessage = IotDeviceMessage.buildStateOffline(); | ||
| 261 | + deviceMessageService.sendDeviceMessage(offlineMessage, connectionInfo.getProductKey(), | ||
| 262 | + connectionInfo.getDeviceName(), serverId); | ||
| 373 | } | 263 | } |
| 374 | - } | ||
| 375 | 264 | ||
| 376 | - // TODO @AI:合并到 handleAuthenticationRequest 里; | ||
| 377 | - /** | ||
| 378 | - * 验证设备认证信息 | ||
| 379 | - * | ||
| 380 | - * @param authParams 认证参数 | ||
| 381 | - * @return 是否认证成功 | ||
| 382 | - */ | ||
| 383 | - private boolean validateDeviceAuth(IotDeviceAuthReqDTO authParams) { | ||
| 384 | - try { | ||
| 385 | - CommonResult<Boolean> result = deviceApi.authDevice(new IotDeviceAuthReqDTO() | ||
| 386 | - .setClientId(authParams.getClientId()).setUsername(authParams.getUsername()) | ||
| 387 | - .setPassword(authParams.getPassword())); | ||
| 388 | - result.checkError(); | ||
| 389 | - return BooleanUtil.isTrue(result.getData()); | ||
| 390 | - } catch (Exception e) { | ||
| 391 | - log.error("[validateDeviceAuth][设备认证异常,username: {}]", authParams.getUsername(), e); | ||
| 392 | - return false; | ||
| 393 | - } | 265 | + // 2. 注销连接 |
| 266 | + connectionManager.unregisterConnection(socket); | ||
| 394 | } | 267 | } |
| 395 | 268 | ||
| 396 | - /** | ||
| 397 | - * 发送错误响应 | ||
| 398 | - * | ||
| 399 | - * @param socket 网络连接 | ||
| 400 | - * @param requestId 请求 ID | ||
| 401 | - * @param errorMessage 错误消息 | ||
| 402 | - */ | ||
| 403 | - private void sendErrorResponse(NetSocket socket, String requestId, String errorMessage) { | ||
| 404 | - sendResponse(socket, false, errorMessage, requestId); | ||
| 405 | - } | 269 | + // ===================== 发送响应消息 ===================== |
| 406 | 270 | ||
| 407 | /** | 271 | /** |
| 408 | * 发送成功响应 | 272 | * 发送成功响应 |
| 409 | * | 273 | * |
| 410 | * @param socket 网络连接 | 274 | * @param socket 网络连接 |
| 411 | * @param requestId 请求 ID | 275 | * @param requestId 请求 ID |
| 412 | - * @param message 消息 | ||
| 413 | - */ | ||
| 414 | - @SuppressWarnings("SameParameterValue") | ||
| 415 | - private void sendSuccessResponse(NetSocket socket, String requestId, String message) { | ||
| 416 | - sendResponse(socket, true, message, requestId); | ||
| 417 | - } | ||
| 418 | - | ||
| 419 | - /** | ||
| 420 | - * 解析认证参数 | ||
| 421 | - * | ||
| 422 | - * @param params 参数对象(通常为 Map 类型) | ||
| 423 | - * @return 认证参数 DTO,解析失败时返回 null | 276 | + * @param method 方法名 |
| 277 | + * @param data 响应数据 | ||
| 424 | */ | 278 | */ |
| 425 | - @SuppressWarnings({"unchecked", "DuplicatedCode"}) | ||
| 426 | - private IotDeviceAuthReqDTO parseAuthParams(Object params) { | ||
| 427 | - if (params == null) { | ||
| 428 | - return null; | ||
| 429 | - } | ||
| 430 | - try { | ||
| 431 | - // 参数默认为 Map 类型,直接转换 | ||
| 432 | - if (params instanceof Map) { | ||
| 433 | - Map<String, Object> paramMap = (Map<String, Object>) params; | ||
| 434 | - return new IotDeviceAuthReqDTO() | ||
| 435 | - .setClientId(MapUtil.getStr(paramMap, "clientId")) | ||
| 436 | - .setUsername(MapUtil.getStr(paramMap, "username")) | ||
| 437 | - .setPassword(MapUtil.getStr(paramMap, "password")); | ||
| 438 | - } | ||
| 439 | - // 如果已经是目标类型,直接返回 | ||
| 440 | - if (params instanceof IotDeviceAuthReqDTO) { | ||
| 441 | - return (IotDeviceAuthReqDTO) params; | ||
| 442 | - } | ||
| 443 | - | ||
| 444 | - // 其他情况尝试 JSON 转换 | ||
| 445 | - return JsonUtils.convertObject(params, IotDeviceAuthReqDTO.class); | ||
| 446 | - } catch (Exception e) { | ||
| 447 | - log.error("[parseAuthParams][解析认证参数({})失败]", params, e); | ||
| 448 | - return null; | ||
| 449 | - } | 279 | + private void sendSuccessResponse(NetSocket socket, String requestId, String method, Object data) { |
| 280 | + IotDeviceMessage responseMessage = IotDeviceMessage.replyOf(requestId, method, data, SUCCESS.getCode(), null); | ||
| 281 | + writeResponse(socket, responseMessage); | ||
| 450 | } | 282 | } |
| 451 | 283 | ||
| 452 | /** | 284 | /** |
| 453 | - * 解析注册参数 | 285 | + * 发送错误响应 |
| 454 | * | 286 | * |
| 455 | - * @param params 参数对象(通常为 Map 类型) | ||
| 456 | - * @return 注册参数 DTO,解析失败时返回 null | 287 | + * @param socket 网络连接 |
| 288 | + * @param requestId 请求 ID | ||
| 289 | + * @param method 方法名 | ||
| 290 | + * @param code 错误码 | ||
| 291 | + * @param msg 错误消息 | ||
| 457 | */ | 292 | */ |
| 458 | - @SuppressWarnings({"unchecked", "DuplicatedCode"}) | ||
| 459 | - private IotDeviceRegisterReqDTO parseRegisterParams(Object params) { | ||
| 460 | - if (params == null) { | ||
| 461 | - return null; | ||
| 462 | - } | ||
| 463 | - try { | ||
| 464 | - // 参数默认为 Map 类型,直接转换 | ||
| 465 | - if (params instanceof Map) { | ||
| 466 | - Map<String, Object> paramMap = (Map<String, Object>) params; | ||
| 467 | - return new IotDeviceRegisterReqDTO() | ||
| 468 | - .setProductKey(MapUtil.getStr(paramMap, "productKey")) | ||
| 469 | - .setDeviceName(MapUtil.getStr(paramMap, "deviceName")) | ||
| 470 | - .setProductSecret(MapUtil.getStr(paramMap, "productSecret")); | ||
| 471 | - } | ||
| 472 | - // 如果已经是目标类型,直接返回 | ||
| 473 | - if (params instanceof IotDeviceRegisterReqDTO) { | ||
| 474 | - return (IotDeviceRegisterReqDTO) params; | ||
| 475 | - } | ||
| 476 | - | ||
| 477 | - // 其他情况尝试 JSON 转换 | ||
| 478 | - String jsonStr = JsonUtils.toJsonString(params); | ||
| 479 | - return JsonUtils.parseObject(jsonStr, IotDeviceRegisterReqDTO.class); | ||
| 480 | - } catch (Exception e) { | ||
| 481 | - log.error("[parseRegisterParams][解析注册参数({})失败]", params, e); | ||
| 482 | - return null; | ||
| 483 | - } | 293 | + private void sendErrorResponse(NetSocket socket, String requestId, String method, Integer code, String msg) { |
| 294 | + IotDeviceMessage responseMessage = IotDeviceMessage.replyOf(requestId, method, null, code, msg); | ||
| 295 | + writeResponse(socket, responseMessage); | ||
| 484 | } | 296 | } |
| 485 | 297 | ||
| 486 | /** | 298 | /** |
| 487 | - * 发送注册成功响应(包含 deviceSecret) | 299 | + * 写入响应到 Socket |
| 488 | * | 300 | * |
| 489 | - * @param socket 网络连接 | ||
| 490 | - * @param requestId 请求 ID | ||
| 491 | - * @param registerResp 注册响应 | 301 | + * @param socket 网络连接 |
| 302 | + * @param responseMessage 响应消息 | ||
| 492 | */ | 303 | */ |
| 493 | - private void sendRegisterSuccessResponse(NetSocket socket, String requestId, | ||
| 494 | - IotDeviceRegisterRespDTO registerResp) { | ||
| 495 | - try { | ||
| 496 | - // 1. 构建响应消息(参考 HTTP 返回格式,直接返回 IotDeviceRegisterRespDTO) | ||
| 497 | - IotDeviceMessage responseMessage = IotDeviceMessage.replyOf(requestId, | ||
| 498 | - IotDeviceMessageMethodEnum.DEVICE_REGISTER.getMethod(), registerResp, 0, null); | ||
| 499 | - // 2. 序列化 + 帧编码 | ||
| 500 | - byte[] serializedData = serializer.serialize(responseMessage); | ||
| 501 | - Buffer frameData = codec.encode(serializedData); | ||
| 502 | - socket.write(frameData); | ||
| 503 | - } catch (Exception e) { | ||
| 504 | - log.error("[sendRegisterSuccessResponse][发送注册成功响应失败,requestId: {}]", requestId, e); | ||
| 505 | - } | 304 | + private void writeResponse(NetSocket socket, IotDeviceMessage responseMessage) { |
| 305 | + byte[] serializedData = serializer.serialize(responseMessage); | ||
| 306 | + Buffer frameData = codec.encode(serializedData); | ||
| 307 | + socket.write(frameData); | ||
| 506 | } | 308 | } |
| 507 | 309 | ||
| 508 | } | 310 | } |
| 509 | \ No newline at end of file | 311 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/manager/IotTcpConnectionManager.java
| @@ -4,7 +4,6 @@ import io.vertx.core.buffer.Buffer; | @@ -4,7 +4,6 @@ import io.vertx.core.buffer.Buffer; | ||
| 4 | import io.vertx.core.net.NetSocket; | 4 | import io.vertx.core.net.NetSocket; |
| 5 | import lombok.Data; | 5 | import lombok.Data; |
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | -import org.springframework.stereotype.Component; | ||
| 8 | 7 | ||
| 9 | import java.util.Map; | 8 | import java.util.Map; |
| 10 | import java.util.concurrent.ConcurrentHashMap; | 9 | import java.util.concurrent.ConcurrentHashMap; |
| @@ -20,7 +19,6 @@ import java.util.concurrent.ConcurrentHashMap; | @@ -20,7 +19,6 @@ import java.util.concurrent.ConcurrentHashMap; | ||
| 20 | * @author 芋道源码 | 19 | * @author 芋道源码 |
| 21 | */ | 20 | */ |
| 22 | @Slf4j | 21 | @Slf4j |
| 23 | -@Component | ||
| 24 | public class IotTcpConnectionManager { | 22 | public class IotTcpConnectionManager { |
| 25 | 23 | ||
| 26 | /** | 24 | /** |
| @@ -74,22 +72,6 @@ public class IotTcpConnectionManager { | @@ -74,22 +72,6 @@ public class IotTcpConnectionManager { | ||
| 74 | } | 72 | } |
| 75 | 73 | ||
| 76 | /** | 74 | /** |
| 77 | - * 检查连接是否已认证 | ||
| 78 | - */ | ||
| 79 | - public boolean isAuthenticated(NetSocket socket) { | ||
| 80 | - ConnectionInfo info = connectionMap.get(socket); | ||
| 81 | - return info != null; | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - // TODO @AI:是不是可以去掉;因为现在只有认证成功的,才会注册连接; | ||
| 85 | - /** | ||
| 86 | - * 检查连接是否未认证 | ||
| 87 | - */ | ||
| 88 | - public boolean isNotAuthenticated(NetSocket socket) { | ||
| 89 | - return !isAuthenticated(socket); | ||
| 90 | - } | ||
| 91 | - | ||
| 92 | - /** | ||
| 93 | * 获取连接信息 | 75 | * 获取连接信息 |
| 94 | */ | 76 | */ |
| 95 | public ConnectionInfo getConnectionInfo(NetSocket socket) { | 77 | public ConnectionInfo getConnectionInfo(NetSocket socket) { |