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) {
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
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地址查找设备
DeviceEntity device = deviceService.getDeviceByMacAddress(macAddress);
if (device == null) {
@@ -98,4 +98,14 @@ public interface DeviceService extends BaseService<DeviceEntity> {
*/
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)
* @return 认证token字符串
*/
private String generateWebSocketToken(String clientId, String username)
public String generateWebSocketToken(String clientId, String username)
throws NoSuchAlgorithmException, InvalidKeyException {
// 从系统参数获取密钥
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.service.SysParamsService;
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
public class ServerSideManageController {
private final SysParamsService sysParamsService;
private final DeviceService deviceService;
private final RedisUtils redisUtils;
private static final ObjectMapper objectMapper;
static {
objectMapper = new ObjectMapper();
@@ -85,9 +89,22 @@ public class ServerSideManageController {
return false;
}
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();
headers.add("device-id", UUID.randomUUID().toString());
headers.add("client-id", UUID.randomUUID().toString());
headers.add("device-id", deviceId);
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()
.connectTimeout(3, TimeUnit.SECONDS)