fix:修复服务器管理页面WebSocket连接失败和消息丢弃问题

This commit is contained in:
3030332422
2025-12-25 18:11:03 +08:00
parent 9541e85600
commit dbd179e507
5 changed files with 46 additions and 3 deletions
@@ -159,4 +159,11 @@ public class RedisKeys {
public static String getKnowledgeBaseCacheKey(String datasetId) { public static String getKnowledgeBaseCacheKey(String datasetId) {
return "knowledge:base:" + datasetId; return "knowledge:base:" + datasetId;
} }
/**
* 获取临时注册设备标记key
*/
public static String getTmpRegisterMacKey(String deviceId) {
return "tmp_register_mac:" + deviceId;
}
} }
@@ -106,6 +106,15 @@ public class ConfigServiceImpl implements ConfigService {
@Override @Override
public Map<String, Object> getAgentModels(String macAddress, Map<String, String> selectedModule) { public Map<String, Object> getAgentModels(String macAddress, Map<String, String> selectedModule) {
// 检查是否为管理控制台请求
String redisKey = RedisKeys.getTmpRegisterMacKey(macAddress);
Object isAdminRequest = redisUtils.get(redisKey);
if (isAdminRequest != null && "true".equals(isAdminRequest)) {
// 管理控制台请求,返回getConfig的结果
redisUtils.delete(redisKey); // 使用后清理
return (Map<String, Object>) getConfig(true);
}
// 根据MAC地址查找设备 // 根据MAC地址查找设备
DeviceEntity device = deviceService.getDeviceByMacAddress(macAddress); DeviceEntity device = deviceService.getDeviceByMacAddress(macAddress);
if (device == null) { if (device == null) {
@@ -98,4 +98,14 @@ public interface DeviceService extends BaseService<DeviceEntity> {
*/ */
void updateDeviceConnectionInfo(String agentId, String deviceId, String appVersion); void updateDeviceConnectionInfo(String agentId, String deviceId, String appVersion);
/**
* 生成WebSocket认证token
*
* @param clientId 客户端ID
* @param username 用户名(通常为deviceId)
* @return 认证token字符串
* @throws Exception 生成token时的异常
*/
String generateWebSocketToken(String clientId, String username) throws Exception;
} }
@@ -518,7 +518,7 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
* @param username 用户名 (通常为deviceId/macAddress) * @param username 用户名 (通常为deviceId/macAddress)
* @return 认证token字符串 * @return 认证token字符串
*/ */
private String generateWebSocketToken(String clientId, String username) public String generateWebSocketToken(String clientId, String username)
throws NoSuchAlgorithmException, InvalidKeyException { throws NoSuchAlgorithmException, InvalidKeyException {
// 从系统参数获取密钥 // 从系统参数获取密钥
String secretKey = sysParamsService.getValue(Constant.SERVER_SECRET, false); String secretKey = sysParamsService.getValue(Constant.SERVER_SECRET, false);
@@ -31,6 +31,8 @@ import xiaozhi.modules.sys.dto.ServerActionResponseDTO;
import xiaozhi.modules.sys.enums.ServerActionEnum; import xiaozhi.modules.sys.enums.ServerActionEnum;
import xiaozhi.modules.sys.service.SysParamsService; import xiaozhi.modules.sys.service.SysParamsService;
import xiaozhi.modules.sys.utils.WebSocketClientManager; import xiaozhi.modules.sys.utils.WebSocketClientManager;
import xiaozhi.modules.device.service.DeviceService;
import xiaozhi.common.redis.RedisUtils;
/** /**
* 服务端管理控制器 * 服务端管理控制器
@@ -41,6 +43,8 @@ import xiaozhi.modules.sys.utils.WebSocketClientManager;
@AllArgsConstructor @AllArgsConstructor
public class ServerSideManageController { public class ServerSideManageController {
private final SysParamsService sysParamsService; private final SysParamsService sysParamsService;
private final DeviceService deviceService;
private final RedisUtils redisUtils;
private static final ObjectMapper objectMapper; private static final ObjectMapper objectMapper;
static { static {
objectMapper = new ObjectMapper(); objectMapper = new ObjectMapper();
@@ -85,9 +89,22 @@ public class ServerSideManageController {
return false; return false;
} }
String serverSK = sysParamsService.getValue(Constant.SERVER_SECRET, true); String serverSK = sysParamsService.getValue(Constant.SERVER_SECRET, true);
String deviceId = UUID.randomUUID().toString();
String clientId = UUID.randomUUID().toString();
String redisKey = xiaozhi.common.redis.RedisKeys.getTmpRegisterMacKey(deviceId);
redisUtils.set(redisKey, "true", 300); // 5分钟有效期
WebSocketHttpHeaders headers = new WebSocketHttpHeaders(); WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
headers.add("device-id", UUID.randomUUID().toString()); headers.add("device-id", deviceId);
headers.add("client-id", UUID.randomUUID().toString()); headers.add("client-id", clientId);
try {
String token = deviceService.generateWebSocketToken(clientId, deviceId);
headers.add("authorization", "Bearer " + token);
} catch (Exception e) {
throw new RenException(ErrorCode.WEB_SOCKET_CONNECT_FAILED);
}
try (WebSocketClientManager client = new WebSocketClientManager.Builder() try (WebSocketClientManager client = new WebSocketClientManager.Builder()
.connectTimeout(3, TimeUnit.SECONDS) .connectTimeout(3, TimeUnit.SECONDS)