|
|
@@ -1,12 +1,12 @@
|
|
|
package cn.iocoder.yudao.module.iot.gateway.protocol.tcp.router;
|
|
|
|
|
|
import cn.hutool.core.map.MapUtil;
|
|
|
+import cn.hutool.core.util.BooleanUtil;
|
|
|
import cn.hutool.core.util.IdUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.extra.spring.SpringUtil;
|
|
|
-import cn.hutool.json.JSONObject;
|
|
|
-import cn.hutool.json.JSONUtil;
|
|
|
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;
|
|
|
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
|
|
|
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceRespDTO;
|
|
|
@@ -21,12 +21,8 @@ import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessa
|
|
|
import io.vertx.core.Handler;
|
|
|
import io.vertx.core.buffer.Buffer;
|
|
|
import io.vertx.core.net.NetSocket;
|
|
|
-import lombok.AllArgsConstructor;
|
|
|
-import lombok.Data;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
-
|
|
|
/**
|
|
|
* TCP 上行消息处理器
|
|
|
*
|
|
|
@@ -77,31 +73,55 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
|
|
|
});
|
|
|
|
|
|
// 设置消息处理器
|
|
|
- socket.handler(buffer -> processMessage(clientId, buffer, socket));
|
|
|
+ socket.handler(buffer -> {
|
|
|
+ try {
|
|
|
+ processMessage(clientId, buffer, socket);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("[handle][消息解码失败,断开连接,客户端 ID: {},地址: {},错误: {}]",
|
|
|
+ clientId, socket.remoteAddress(), e.getMessage());
|
|
|
+ cleanupConnection(socket);
|
|
|
+ socket.close();
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 处理消息
|
|
|
+ *
|
|
|
+ * @param clientId 客户端 ID
|
|
|
+ * @param buffer 消息
|
|
|
+ * @param socket 网络连接
|
|
|
+ * @throws Exception 消息解码失败时抛出异常
|
|
|
*/
|
|
|
- private void processMessage(String clientId, Buffer buffer, NetSocket socket) {
|
|
|
+ private void processMessage(String clientId, Buffer buffer, NetSocket socket) throws Exception {
|
|
|
+ // 1. 基础检查
|
|
|
+ if (buffer == null || buffer.length() == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 获取消息格式类型
|
|
|
+ String codecType = getMessageCodecType(buffer, socket);
|
|
|
+
|
|
|
+ // 3. 解码消息
|
|
|
+ IotDeviceMessage message;
|
|
|
try {
|
|
|
- // 1.1 数据包基础检查
|
|
|
- if (buffer.length() == 0) {
|
|
|
- return;
|
|
|
- }
|
|
|
- // 1.2 解码消息
|
|
|
- MessageInfo messageInfo = decodeMessage(buffer);
|
|
|
- if (messageInfo == null) {
|
|
|
- return;
|
|
|
+ message = deviceMessageService.decodeDeviceMessage(buffer.getBytes(), codecType);
|
|
|
+ if (message == null) {
|
|
|
+ throw new Exception("解码后消息为空");
|
|
|
}
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 消息格式错误时抛出异常,由上层处理连接断开
|
|
|
+ throw new Exception("消息解码失败: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
|
|
|
- // 2. 根据消息类型路由处理
|
|
|
- if (isAuthRequest(messageInfo.message)) {
|
|
|
+ // 4. 根据消息类型路由处理
|
|
|
+ try {
|
|
|
+ if (AUTH_METHOD.equals(message.getMethod())) {
|
|
|
// 认证请求
|
|
|
- handleAuthenticationRequest(clientId, messageInfo, socket);
|
|
|
+ handleAuthenticationRequest(clientId, message, codecType, socket);
|
|
|
} else {
|
|
|
// 业务消息
|
|
|
- handleBusinessRequest(clientId, messageInfo, socket);
|
|
|
+ handleBusinessRequest(clientId, message, codecType, socket);
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
log.error("[processMessage][处理消息失败,客户端 ID: {}]", clientId, e);
|
|
|
@@ -110,226 +130,158 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
|
|
|
|
|
|
/**
|
|
|
* 处理认证请求
|
|
|
+ *
|
|
|
+ * @param clientId 客户端 ID
|
|
|
+ * @param message 消息信息
|
|
|
+ * @param codecType 消息编解码类型
|
|
|
+ * @param socket 网络连接
|
|
|
*/
|
|
|
- private void handleAuthenticationRequest(String clientId, MessageInfo messageInfo, NetSocket socket) {
|
|
|
+ private void handleAuthenticationRequest(String clientId, IotDeviceMessage message, String codecType,
|
|
|
+ NetSocket socket) {
|
|
|
try {
|
|
|
// 1.1 解析认证参数
|
|
|
- IotDeviceMessage message = messageInfo.message;
|
|
|
- AuthParams authParams = parseAuthParams(message.getParams());
|
|
|
+ IotDeviceAuthReqDTO authParams = JsonUtils.parseObject(message.getParams().toString(),
|
|
|
+ IotDeviceAuthReqDTO.class);
|
|
|
if (authParams == null) {
|
|
|
- sendError(socket, message.getRequestId(), "认证参数不完整", messageInfo.codecType);
|
|
|
+ sendErrorResponse(socket, message.getRequestId(), "认证参数不完整", codecType);
|
|
|
return;
|
|
|
}
|
|
|
// 1.2 执行认证
|
|
|
- if (!authenticateDevice(authParams)) {
|
|
|
+ if (!validateDeviceAuth(authParams)) {
|
|
|
log.warn("[handleAuthenticationRequest][认证失败,客户端 ID: {},username: {}]",
|
|
|
- clientId, authParams.username);
|
|
|
- sendError(socket, message.getRequestId(), "认证失败", messageInfo.codecType);
|
|
|
+ clientId, authParams.getUsername());
|
|
|
+ sendErrorResponse(socket, message.getRequestId(), "认证失败", codecType);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 2.1 解析设备信息
|
|
|
- IotDeviceAuthUtils.DeviceInfo deviceInfo = IotDeviceAuthUtils.parseUsername(authParams.username);
|
|
|
+ IotDeviceAuthUtils.DeviceInfo deviceInfo = IotDeviceAuthUtils.parseUsername(authParams.getUsername());
|
|
|
if (deviceInfo == null) {
|
|
|
- sendError(socket, message.getRequestId(), "解析设备信息失败", messageInfo.codecType);
|
|
|
+ sendErrorResponse(socket, message.getRequestId(), "解析设备信息失败", codecType);
|
|
|
return;
|
|
|
}
|
|
|
// 2.2 获取设备信息
|
|
|
IotDeviceRespDTO device = deviceService.getDeviceFromCache(deviceInfo.getProductKey(),
|
|
|
deviceInfo.getDeviceName());
|
|
|
if (device == null) {
|
|
|
- sendError(socket, message.getRequestId(), "设备不存在", messageInfo.codecType);
|
|
|
+ sendErrorResponse(socket, message.getRequestId(), "设备不存在", codecType);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 3. 注册连接并发送成功响应
|
|
|
- registerConnection(socket, device, deviceInfo, authParams.clientId);
|
|
|
- sendOnlineMessage(deviceInfo);
|
|
|
- sendSuccess(socket, message.getRequestId(), "认证成功", messageInfo.codecType);
|
|
|
+ // 3.1 注册连接
|
|
|
+ registerConnection(socket, device, clientId, codecType);
|
|
|
+ // 3.2 发送上线消息
|
|
|
+ sendOnlineMessage(device);
|
|
|
+ // 3.3 发送成功响应
|
|
|
+ sendSuccessResponse(socket, message.getRequestId(), "认证成功", codecType);
|
|
|
log.info("[handleAuthenticationRequest][认证成功,设备 ID: {},设备名: {}]",
|
|
|
- device.getId(), deviceInfo.getDeviceName());
|
|
|
+ device.getId(), device.getDeviceName());
|
|
|
} catch (Exception e) {
|
|
|
log.error("[handleAuthenticationRequest][认证处理异常,客户端 ID: {}]", clientId, e);
|
|
|
- sendError(socket, messageInfo.message.getRequestId(), "认证处理异常", messageInfo.codecType);
|
|
|
+ sendErrorResponse(socket, message.getRequestId(), "认证处理异常", codecType);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 处理业务请求
|
|
|
+ *
|
|
|
+ * @param clientId 客户端 ID
|
|
|
+ * @param message 消息信息
|
|
|
+ * @param codecType 消息编解码类型
|
|
|
+ * @param socket 网络连接
|
|
|
*/
|
|
|
- private void handleBusinessRequest(String clientId, MessageInfo messageInfo, NetSocket socket) {
|
|
|
+ private void handleBusinessRequest(String clientId, IotDeviceMessage message, String codecType, NetSocket socket) {
|
|
|
try {
|
|
|
// 1. 检查认证状态
|
|
|
if (connectionManager.isNotAuthenticated(socket)) {
|
|
|
log.warn("[handleBusinessRequest][设备未认证,客户端 ID: {}]", clientId);
|
|
|
- sendError(socket, messageInfo.message.getRequestId(), "请先进行认证", messageInfo.codecType);
|
|
|
+ sendErrorResponse(socket, message.getRequestId(), "请先进行认证", codecType);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 2. 获取认证信息并处理业务消息
|
|
|
- IotTcpConnectionManager.AuthInfo authInfo = connectionManager.getAuthInfo(socket);
|
|
|
- processBusinessMessage(clientId, messageInfo.message, authInfo);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("[handleBusinessRequest][业务请求处理异常,客户端 ID: {}]", clientId, e);
|
|
|
- }
|
|
|
- }
|
|
|
+ IotTcpConnectionManager.ConnectionInfo connectionInfo = connectionManager.getConnectionInfo(socket);
|
|
|
|
|
|
- // TODO @haohao:processBusinessMessage 这个小方法,直接融合到 handleBusinessRequest 里?读起来更聚集点
|
|
|
- /**
|
|
|
- * 处理业务消息
|
|
|
- */
|
|
|
- private void processBusinessMessage(String clientId, IotDeviceMessage message,
|
|
|
- IotTcpConnectionManager.AuthInfo authInfo) {
|
|
|
- try {
|
|
|
- message.setDeviceId(authInfo.getDeviceId());
|
|
|
- message.setServerId(serverId);
|
|
|
- // 发送到消息总线
|
|
|
- deviceMessageService.sendDeviceMessage(message, authInfo.getProductKey(),
|
|
|
- authInfo.getDeviceName(), serverId);
|
|
|
+ // 3. 发送消息到消息总线
|
|
|
+ deviceMessageService.sendDeviceMessage(message, connectionInfo.getProductKey(),
|
|
|
+ connectionInfo.getDeviceName(), serverId);
|
|
|
} catch (Exception e) {
|
|
|
- log.error("[processBusinessMessage][业务消息处理失败,客户端 ID: {},消息 ID: {}]",
|
|
|
- clientId, message.getId(), e);
|
|
|
+ log.error("[handleBusinessRequest][业务请求处理异常,客户端 ID: {}]", clientId, e);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 解码消息
|
|
|
+ * 获取消息编解码类型
|
|
|
*
|
|
|
* @param buffer 消息
|
|
|
+ * @param socket 网络连接
|
|
|
+ * @return 消息编解码类型
|
|
|
*/
|
|
|
- private MessageInfo decodeMessage(Buffer buffer) {
|
|
|
- if (buffer == null || buffer.length() == 0) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- // 1. 快速检测消息格式类型
|
|
|
- // TODO @haohao:是不是进一步优化?socket 建立认证后,那条消息已经定义了所有消息的格式哈?
|
|
|
- String codecType = detectMessageFormat(buffer);
|
|
|
- try {
|
|
|
- // 2. 使用检测到的格式进行解码
|
|
|
- IotDeviceMessage message = deviceMessageService.decodeDeviceMessage(buffer.getBytes(), codecType);
|
|
|
- if (message == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- return new MessageInfo(message, codecType);
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("[decodeMessage][消息解码失败,格式: {},数据长度: {},错误: {}]",
|
|
|
- codecType, buffer.length(), e.getMessage());
|
|
|
- // TODO @haohao:一般消息格式不对,应该抛出异常,断开连接居多?
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检测消息格式类型
|
|
|
- * 优化性能:避免不必要的字符串转换
|
|
|
- */
|
|
|
- private String detectMessageFormat(Buffer buffer) {
|
|
|
- // TODO @haohao:是不是 IotTcpBinaryDeviceMessageCodec 提供一个 isBinaryFormat 方法哈?
|
|
|
- // 默认使用 JSON
|
|
|
- if (buffer.length() == 0) {
|
|
|
- return CODEC_TYPE_JSON;
|
|
|
- }
|
|
|
-
|
|
|
- // 1. 优先检测二进制格式(检查魔术字节 0x7E)
|
|
|
- if (isBinaryFormat(buffer)) {
|
|
|
- return CODEC_TYPE_BINARY;
|
|
|
- }
|
|
|
-
|
|
|
- // 2. 检测 JSON 格式(检查前几个有效字符)
|
|
|
- // TODO @haohao:这个检测去掉?直接 return CODEC_TYPE_JSON 更简洁一点。
|
|
|
- if (isJsonFormat(buffer)) {
|
|
|
- return CODEC_TYPE_JSON;
|
|
|
+ private String getMessageCodecType(Buffer buffer, NetSocket socket) {
|
|
|
+ // 1. 如果已认证,优先使用缓存的编解码类型
|
|
|
+ IotTcpConnectionManager.ConnectionInfo connectionInfo = connectionManager.getConnectionInfo(socket);
|
|
|
+ if (connectionInfo != null && connectionInfo.isAuthenticated() &&
|
|
|
+ StrUtil.isNotBlank(connectionInfo.getCodecType())) {
|
|
|
+ return connectionInfo.getCodecType();
|
|
|
}
|
|
|
|
|
|
- // 3. 默认尝试 JSON 格式
|
|
|
- return CODEC_TYPE_JSON;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检测二进制格式
|
|
|
- * 通过检查魔术字节快速识别,避免完整字符串转换
|
|
|
- */
|
|
|
- private boolean isBinaryFormat(Buffer buffer) {
|
|
|
- // 二进制协议最小长度检查
|
|
|
- if (buffer.length() < 8) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- // 检查魔术字节 0x7E(二进制协议的第一个字节)
|
|
|
- byte firstByte = buffer.getByte(0);
|
|
|
- return firstByte == (byte) 0x7E;
|
|
|
- } catch (Exception e) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检测 JSON 格式
|
|
|
- * 只检查前几个有效字符,避免完整字符串转换
|
|
|
- */
|
|
|
- private boolean isJsonFormat(Buffer buffer) {
|
|
|
- try {
|
|
|
- // 检查前 64 个字节或整个缓冲区(取较小值)
|
|
|
- int checkLength = Math.min(buffer.length(), 64);
|
|
|
- String prefix = buffer.getString(0, checkLength, StandardCharsets.UTF_8.name());
|
|
|
-
|
|
|
- if (StrUtil.isBlank(prefix)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- String trimmed = prefix.trim();
|
|
|
- // JSON 格式必须以 { 或 [ 开头
|
|
|
- return trimmed.startsWith("{") || trimmed.startsWith("[");
|
|
|
-
|
|
|
- } catch (Exception e) {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ // 2. 未认证时检测消息格式类型
|
|
|
+ return IotTcpBinaryDeviceMessageCodec.isBinaryFormatQuick(buffer.getBytes()) ? CODEC_TYPE_BINARY
|
|
|
+ : CODEC_TYPE_JSON;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 注册连接信息
|
|
|
+ *
|
|
|
+ * @param socket 网络连接
|
|
|
+ * @param device 设备
|
|
|
+ * @param clientId 客户端 ID
|
|
|
+ * @param codecType 消息编解码类型
|
|
|
*/
|
|
|
private void registerConnection(NetSocket socket, IotDeviceRespDTO device,
|
|
|
- IotDeviceAuthUtils.DeviceInfo deviceInfo, String clientId) {
|
|
|
- // TODO @haohao:AuthInfo 的创建,放在 connectionManager 里构建貌似会更收敛一点?
|
|
|
- // 创建认证信息
|
|
|
- IotTcpConnectionManager.AuthInfo authInfo = new IotTcpConnectionManager.AuthInfo()
|
|
|
+ String clientId, String codecType) {
|
|
|
+ IotTcpConnectionManager.ConnectionInfo connectionInfo = new IotTcpConnectionManager.ConnectionInfo()
|
|
|
.setDeviceId(device.getId())
|
|
|
- .setProductKey(deviceInfo.getProductKey())
|
|
|
- .setDeviceName(deviceInfo.getDeviceName())
|
|
|
- .setClientId(clientId);
|
|
|
+ .setProductKey(device.getProductKey())
|
|
|
+ .setDeviceName(device.getDeviceName())
|
|
|
+ .setClientId(clientId)
|
|
|
+ .setCodecType(codecType)
|
|
|
+ .setAuthenticated(true);
|
|
|
// 注册连接
|
|
|
- connectionManager.registerConnection(socket, device.getId(), authInfo);
|
|
|
+ connectionManager.registerConnection(socket, device.getId(), connectionInfo);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 发送设备上线消息
|
|
|
+ *
|
|
|
+ * @param device 设备信息
|
|
|
*/
|
|
|
- private void sendOnlineMessage(IotDeviceAuthUtils.DeviceInfo deviceInfo) {
|
|
|
+ private void sendOnlineMessage(IotDeviceRespDTO device) {
|
|
|
try {
|
|
|
IotDeviceMessage onlineMessage = IotDeviceMessage.buildStateUpdateOnline();
|
|
|
- deviceMessageService.sendDeviceMessage(onlineMessage, deviceInfo.getProductKey(),
|
|
|
- deviceInfo.getDeviceName(), serverId);
|
|
|
+ deviceMessageService.sendDeviceMessage(onlineMessage, device.getProductKey(),
|
|
|
+ device.getDeviceName(), serverId);
|
|
|
} catch (Exception e) {
|
|
|
- log.error("[sendOnlineMessage][发送上线消息失败,设备: {}]", deviceInfo.getDeviceName(), e);
|
|
|
+ log.error("[sendOnlineMessage][发送上线消息失败,设备: {}]", device.getDeviceName(), e);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 清理连接
|
|
|
+ *
|
|
|
+ * @param socket 网络连接
|
|
|
*/
|
|
|
private void cleanupConnection(NetSocket socket) {
|
|
|
try {
|
|
|
- // 发送离线消息(如果已认证)
|
|
|
- IotTcpConnectionManager.AuthInfo authInfo = connectionManager.getAuthInfo(socket);
|
|
|
- if (authInfo != null) {
|
|
|
+ // 1. 发送离线消息(如果已认证)
|
|
|
+ IotTcpConnectionManager.ConnectionInfo connectionInfo = connectionManager.getConnectionInfo(socket);
|
|
|
+ if (connectionInfo != null) {
|
|
|
IotDeviceMessage offlineMessage = IotDeviceMessage.buildStateOffline();
|
|
|
- deviceMessageService.sendDeviceMessage(offlineMessage, authInfo.getProductKey(),
|
|
|
- authInfo.getDeviceName(), serverId);
|
|
|
+ deviceMessageService.sendDeviceMessage(offlineMessage, connectionInfo.getProductKey(),
|
|
|
+ connectionInfo.getDeviceName(), serverId);
|
|
|
}
|
|
|
|
|
|
- // 注销连接
|
|
|
+ // 2. 注销连接
|
|
|
connectionManager.unregisterConnection(socket);
|
|
|
} catch (Exception e) {
|
|
|
log.error("[cleanupConnection][清理连接失败]", e);
|
|
|
@@ -338,6 +290,12 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
|
|
|
|
|
|
/**
|
|
|
* 发送响应消息
|
|
|
+ *
|
|
|
+ * @param socket 网络连接
|
|
|
+ * @param success 是否成功
|
|
|
+ * @param message 消息
|
|
|
+ * @param requestId 请求 ID
|
|
|
+ * @param codecType 消息编解码类型
|
|
|
*/
|
|
|
private void sendResponse(NetSocket socket, boolean success, String message, String requestId, String codecType) {
|
|
|
try {
|
|
|
@@ -346,8 +304,9 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
|
|
|
.put("message", message)
|
|
|
.build();
|
|
|
|
|
|
+ int code = success ? 0 : 401;
|
|
|
IotDeviceMessage responseMessage = IotDeviceMessage.replyOf(requestId, AUTH_METHOD, responseData,
|
|
|
- success ? 0 : 401, message);
|
|
|
+ code, message);
|
|
|
|
|
|
byte[] encodedData = deviceMessageService.encodeDeviceMessage(responseMessage, codecType);
|
|
|
socket.write(Buffer.buffer(encodedData));
|
|
|
@@ -357,94 +316,47 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // ==================== 辅助方法 ====================
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断是否为认证请求
|
|
|
- */
|
|
|
- private boolean isAuthRequest(IotDeviceMessage message) {
|
|
|
- return AUTH_METHOD.equals(message.getMethod());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 解析认证参数
|
|
|
- */
|
|
|
- private AuthParams parseAuthParams(Object params) {
|
|
|
- if (params == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- try {
|
|
|
- JSONObject paramsJson = params instanceof JSONObject ? (JSONObject) params
|
|
|
- : JSONUtil.parseObj(params.toString());
|
|
|
- String clientId = paramsJson.getStr("clientId");
|
|
|
- String username = paramsJson.getStr("username");
|
|
|
- String password = paramsJson.getStr("password");
|
|
|
- return StrUtil.hasBlank(clientId, username, password) ? null
|
|
|
- : new AuthParams(clientId, username, password);
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("[parseAuthParams][解析认证参数失败]", e);
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
- * 认证设备
|
|
|
+ * 验证设备认证信息
|
|
|
+ *
|
|
|
+ * @param authParams 认证参数
|
|
|
+ * @return 是否认证成功
|
|
|
*/
|
|
|
- private boolean authenticateDevice(AuthParams authParams) {
|
|
|
+ private boolean validateDeviceAuth(IotDeviceAuthReqDTO authParams) {
|
|
|
try {
|
|
|
CommonResult<Boolean> result = deviceApi.authDevice(new IotDeviceAuthReqDTO()
|
|
|
- .setClientId(authParams.clientId)
|
|
|
- .setUsername(authParams.username)
|
|
|
- .setPassword(authParams.password));
|
|
|
- return result.isSuccess() && Boolean.TRUE.equals(result.getData());
|
|
|
+ .setClientId(authParams.getClientId()).setUsername(authParams.getUsername())
|
|
|
+ .setPassword(authParams.getPassword()));
|
|
|
+ result.checkError();
|
|
|
+ return BooleanUtil.isTrue(result.getData());
|
|
|
} catch (Exception e) {
|
|
|
- log.error("[authenticateDevice][设备认证异常,username: {}]", authParams.username, e);
|
|
|
+ log.error("[validateDeviceAuth][设备认证异常,username: {}]", authParams.getUsername(), e);
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // TODO @haohao:改成 sendErrorResponse sendSuccessResponse 更清晰点?
|
|
|
-
|
|
|
/**
|
|
|
* 发送错误响应
|
|
|
+ *
|
|
|
+ * @param socket 网络连接
|
|
|
+ * @param requestId 请求 ID
|
|
|
+ * @param errorMessage 错误消息
|
|
|
+ * @param codecType 消息编解码类型
|
|
|
*/
|
|
|
- private void sendError(NetSocket socket, String requestId, String errorMessage, String codecType) {
|
|
|
+ private void sendErrorResponse(NetSocket socket, String requestId, String errorMessage, String codecType) {
|
|
|
sendResponse(socket, false, errorMessage, requestId, codecType);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 发送成功响应
|
|
|
+ *
|
|
|
+ * @param socket 网络连接
|
|
|
+ * @param requestId 请求 ID
|
|
|
+ * @param message 消息
|
|
|
+ * @param codecType 消息编解码类型
|
|
|
*/
|
|
|
- private void sendSuccess(NetSocket socket, String requestId, String message, String codecType) {
|
|
|
+ private void sendSuccessResponse(NetSocket socket, String requestId, String message, String codecType) {
|
|
|
sendResponse(socket, true, message, requestId, codecType);
|
|
|
}
|
|
|
|
|
|
- // ==================== 内部类 ====================
|
|
|
-
|
|
|
- // TODO @haohao:IotDeviceAuthReqDTO 复用这个?
|
|
|
- /**
|
|
|
- * 认证参数
|
|
|
- */
|
|
|
- @Data
|
|
|
- @AllArgsConstructor
|
|
|
- private static class AuthParams {
|
|
|
-
|
|
|
- private final String clientId;
|
|
|
- private final String username;
|
|
|
- private final String password;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 消息信息
|
|
|
- */
|
|
|
- @Data
|
|
|
- @AllArgsConstructor
|
|
|
- private static class MessageInfo {
|
|
|
-
|
|
|
- private final IotDeviceMessage message;
|
|
|
-
|
|
|
- private final String codecType;
|
|
|
-
|
|
|
- }
|
|
|
}
|