diff --git a/lib/core/network/net_message_dispatcher.dart b/lib/core/network/net_message_dispatcher.dart index 0eca1058..09d3e640 100644 --- a/lib/core/network/net_message_dispatcher.dart +++ b/lib/core/network/net_message_dispatcher.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:flutter/cupertino.dart'; +import 'package:get_it/get_it.dart'; import 'package:maibu_satabot_v2/core/logging/i_logger_service.dart'; import 'package:maibu_satabot_v2/features/devices/data/models/device_add_path_point_model.dart'; @@ -20,6 +21,9 @@ class NetMessageDispatcher { // 修改:使用回调函数获取 AppState final Function? getAppState; + final ILoggerService _logger = GetIt.I(); + + // 🔥 新增:ACK 握手状态管理 (仅新模式使用) int _expectedPointIndex = -1; // 期望收到的点编号 bool _waitingForAck = false; // 是否正在等待 ACK 确认 @@ -30,7 +34,8 @@ class NetMessageDispatcher { // 🔥 新增:设置期望收到的点编号(供 PathPlanner 调用) void setExpectedPointIndex(int index) { _expectedPointIndex = index; - debugPrint('🎯 [Dispatcher-ACK] 设置期望点编号:$index'); + //debugPrint('🎯 [Dispatcher-ACK] 设置期望点编号:$index'); + _logger.log('[Dispatcher-ACK] 设置期望点编号:$index'); } @@ -43,15 +48,18 @@ class NetMessageDispatcher { /// 示例解析方法:将 0x02 指令解析为 String Stream onStringMessage() { - print("0x02--TCP拦截推送解析开始"); + //print("0x02--TCP拦截推送解析开始"); + _logger.log('0x02--TCP拦截推送解析开始'); return onCommand(0x02).map((p) { try { // 尝试解码 final result = utf8.decode(p.payload, allowMalformed: true); // 允许乱码,防止报错中断流 - print('✅ 解码 0x02 成功:$result'); // 🔥 关键日志:看这里打印了吗? + //print('✅ 解码 0x02 成功:$result'); // 🔥 关键日志:看这里打印了吗? + _logger.log('✅ 解码 0x02 成功:$result'); return result; } catch (e) { - print('❌ 解码 0x02 失败:$e, 原始字节:${p.payload}'); + // print('❌ 解码 0x02 失败:$e, 原始字节:${p.payload}'); + _logger.log('❌ 解码 0x02 失败:$e, 原始字节:${p.payload}'); return ''; // 返回空字符串,避免流中断 } }); @@ -63,19 +71,22 @@ class NetMessageDispatcher { // return onCommand(cmd).map((p) => jsonDecode(utf8.decode(p.payload))); // } Stream> onJsonMessage(int cmd) { - print('🔵 [Dispatcher] 开始监听 0x${cmd.toRadixString(16)} 指令的 JSON 流'); - + //print('🔵 [Dispatcher] 开始监听 0x${cmd.toRadixString(16)} 指令的 JSON 流'); +_logger.log('🔵 [Dispatcher] 监听 0x${cmd.toRadixString(16)} 指令的 JSON 流'); return onCommand(cmd).map((p) { try { final jsonString = utf8.decode(p.payload); - print('🔵 [Dispatcher] 收到 0x${cmd.toRadixString(16)} 原始数据: $jsonString'); - + //print('🔵 [Dispatcher] 收到 0x${cmd.toRadixString(16)} 原始数据: $jsonString'); +_logger + .log('🔵 [Dispatcher] 监听 0x${cmd.toRadixString(16)} 指令的 JSON 流'); final jsonMap = jsonDecode(jsonString); - print('🔵 [Dispatcher] JSON 解析成功:$jsonMap'); + // print('🔵 [Dispatcher] JSON 解析成功:$jsonMap'); + _logger.log('🔵 [Dispatcher] JSON 解析成功:$jsonMap'); return jsonMap; } catch (e) { - print('❌ [Dispatcher] 0x${cmd.toRadixString(16)} JSON 解析失败:$e, payload=${p.payload}'); + //print('❌ [Dispatcher] 0x${cmd.toRadixString(16)} JSON 解析失败:$e, payload=${p.payload}'); + _logger.log('❌ [Dispatcher] 0x${cmd.toRadixString(16)} JSON 解析失败:$e, payload=${p.payload}'); return {}; // 返回空 map,避免流中断 } }); @@ -193,11 +204,12 @@ class NetMessageDispatcher { Stream onPathPlanningResponse() { final devicesCubit = sl(); - debugPrint('[Dispatcher] 开始监听路径规划指令应答 (CMD: 0x01) - 模式:${PathPlanningConfig.getModeDescription()}'); - + //debugPrint('[Dispatcher] 开始监听路径规划指令应答 (CMD: 0x01) - 模式:${PathPlanningConfig.getModeDescription()}'); +_logger.logWithLevel('[Dispatcher] 开始监听路径规划指令应答 (CMD: 0x01) - 模式:${PathPlanningConfig.getModeDescription()}'); // 🔥 根据配置决定使用哪个流 if (PathPlanningConfig.useAckHandshake) { - debugPrint('⚙️ [Dispatcher] 使用 ACK 握手机制'); + //debugPrint('⚙️ [Dispatcher] 使用 ACK 握手机制'); + _logger.logWithLevel('⚙️ [Dispatcher] 使用 ACK 握手机制'); return onPathPlanningResponseWithAck(); } else { debugPrint('⚙️ [Dispatcher] 使用现有逻辑'); @@ -206,7 +218,8 @@ class NetMessageDispatcher { if (getAppState != null) { final currentState = getAppState!(); if (currentState.toString() == 'AppState.none') { - debugPrint('⚠️ [Dispatcher] 当前 AppState 为 none,停止处理路径规划指令'); + //debugPrint('⚠️ [Dispatcher] 当前 AppState 为 none,停止处理路径规划指令'); + _logger.logWithLevel('⚠️ [Dispatcher] 当前 AppState 为 none,停止处理路径规划指令'); return false; } } @@ -224,12 +237,14 @@ class NetMessageDispatcher { fullData[2] == 0x01) { if(fullData[5] == 0x02){ - debugPrint('下位机回复收到指令 - 完整数据包:${fullData.join(" ")}'); + // debugPrint('下位机回复收到指令 - 完整数据包:${fullData.join(" ")}'); + _logger.logWithLevel('下位机回复收到指令 - 完整数据包:${fullData.join(" ")}'); } debugPrint('[Dispatcher] 下位机回复成功 - 完整数据包:${fullData.join(" ")}'); // 检查状态位 (索引 5 对应 payload 的第 2 个字节) if (fullData.length > 5 && fullData[5] == 0x01) { - debugPrint('✅ [Dispatcher] 状态位验证通过:0x01 - 可以发送下一个指令'); + // debugPrint('✅ [Dispatcher] 状态位验证通过:0x01 - 可以发送下一个指令'); + _logger.logWithLevel('✅ [Dispatcher] 状态位验证通过:0x01 - 可以发送下一个指令'); ///取全局的路径规划发送实体 queue /// 发送下一个指令 移除上一条数据 var queue = _pathPlanningService.getQueue(); @@ -241,7 +256,8 @@ class NetMessageDispatcher { }); // 手动停止 //routePlanningRepository.stopRoutePlanning(); - debugPrint('⚠️ [Dispatcher] 队列已经为空,跳过本次响应处理'); + //debugPrint('⚠️ [Dispatcher] 队列已经为空,跳过本次响应处理'); + _logger.logWithLevel('⚠️ [Dispatcher] 队列已经为空,跳过本次响应处理'); return false; } ///更新完成 jwd @@ -252,7 +268,8 @@ class NetMessageDispatcher { deviceAddPathPointModel.latitude, deviceAddPathPointModel.longitude ); - debugPrint("准确更新完成的路径点经纬度,$d,$e"); + // debugPrint("准确更新完成的路径点经纬度,$d,$e"); + _logger.logWithLevel("准确更新完成路径点经纬度,$d,$e"); //去除上一条数据 queue.removeFirst(); /// _pathPlanningService.updateQueue(queue as List); @@ -262,10 +279,12 @@ class NetMessageDispatcher { "${now.minute.toString().padLeft(2, '0')}:" "${now.second.toString().padLeft(2, '0')}"; - debugPrint(' $timeStr [Dispatcher] 准备触发下一个路径点发送,队列剩余:${queue.length}'); + //debugPrint(' $timeStr [Dispatcher] 准备触发下一个路径点发送,队列剩余:${queue.length}'); + _logger.logWithLevel(' $timeStr [Dispatcher] 触发下一个路径点发送,队列剩余:${queue.length}'); ///如果还剩 0 个数据 就停止发送 if (queue.length==0) { - debugPrint('⚠️ [Dispatcher] 队列已空,停止发送'); + //debugPrint('⚠️ [Dispatcher] 队列已空,停止发送'); + _logger.logWithLevel('⚠️ [Dispatcher] 队列已空,停止发送'); // final devicesCubit = sl(); devicesCubit.finishWork(); @@ -274,16 +293,19 @@ class NetMessageDispatcher { }); // 手动停止 routePlanningRepository.stopRoutePlanning(); - debugPrint('⚠️ [Dispatcher] 队列已空,发送停止指令已发送'); + //debugPrint('⚠️ [Dispatcher] 队列已空,发送停止指令已发送'); + _logger.logWithLevel('⚠️ [Dispatcher] 状态位异常:${fullData.length > 5 ? fullData[5].toRadixString(16) : "N/A"}'); return false; } routePlanningRepository.startRoutePlanning(queue); return true; } else { - debugPrint('⚠️ [Dispatcher] 状态位异常:${fullData.length > 5 ? fullData[5].toRadixString(16) : "N/A"}'); + //debugPrint('⚠️ [Dispatcher] 状态位异常:${fullData.length > 5 ? fullData[5].toRadixString(16) : "N/A"}'); + _logger.logWithLevel('⚠️ [Dispatcher] 状态位异常:${fullData.length > 5 ? fullData[5].toRadixString(16) : "N/A"}'); } } else { - debugPrint('❌ [Dispatcher] 协议头验证失败'); + // debugPrint('❌ [Dispatcher] 协议头验证失败'); + _logger.logWithLevel('❌ [Dispatcher] 协议头验证失败'); } return false; diff --git a/lib/core/network/tcp/tcp_client.dart b/lib/core/network/tcp/tcp_client.dart index 252b5a21..42afce31 100644 --- a/lib/core/network/tcp/tcp_client.dart +++ b/lib/core/network/tcp/tcp_client.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/cupertino.dart'; +import 'package:get_it/get_it.dart'; import 'package:maibu_satabot_v2/features/devices/data/repositories/route_planning_repository_impl.dart'; import '../../../features/auth/data/datasources/auth_tcp_datasource.dart'; @@ -13,6 +14,7 @@ import '../../../features/devices/domain/entities/gps_entity.dart'; import '../../../features/devices/domain/entities/running_status_entity.dart'; import '../../../features/devices/domain/usecases/get_user_device_usecase.dart'; import '../../../features/devices/domain/usecases/switch_device_usecase.dart'; +import '../../logging/i_logger_service.dart'; import '../../storage/user_storage.dart'; import '../protocol_decoder.dart'; @@ -27,6 +29,9 @@ class TcpClient { final SwitchDeviceUseCase switchDeviceUseCase; TcpClient(this._userStorage, {required this.getUserDeviceUseCase, required this.switchDeviceUseCase}); + final ILoggerService _logger = GetIt.I(); + + // 新增:心跳定时器 Timer? _heartbeatTimer; Timer? _reconnectTimer; // 重连定时器 @@ -42,7 +47,8 @@ class TcpClient { void disconnects({bool forSwitch = false}) { if (forSwitch) { _isSwitching = true; - debugPrint('🚫 [TCP] 标记为切换断开,将禁止自动重连'); + //debugPrint('🚫 [TCP] 标记为切换断开,将禁止自动重连'); + _logger.logWithLevel('🚫 [TCP] 标记为切换断开,将禁止自动重连'); } // 🔥 关键:立即取消可能已经存在或即将触发的重连定时器 @@ -50,14 +56,16 @@ class TcpClient { _heartbeatTimer?.cancel(); if (_socket != null) { - debugPrint('🔌 [TCP] 物理断开 Socket...'); + //debugPrint('🔌 [TCP] 物理断开 Socket...'); + _logger.logWithLevel('🔌 [TCP] 物理断开 Socket...'); _socket!.destroy(); // 或者 .close() _socket = null; } } // 通过参数配置,不硬编码 Future connect({required String host, required int port}) async { - debugPrint('🔌 [TCP] 开始连接:$host:$port'); // ✅ 必须看到这条 + //debugPrint('🔌 [TCP] 开始连接:$host:$port'); // ✅ 必须看到这条 + _logger.logWithLevel('🔌 [TCP] 开始连接:$host:$port'); _lastHost = host; _lastPort = port; try { @@ -67,10 +75,12 @@ class TcpClient { timeout: const Duration(seconds: 5), ); debugPrint('✅ [TCP] 连接成功!'); // ✅ 必须看到这条 + _logger.logWithLevel('✅ [TCP] 连接成功!'); // 开始认证tcp await _sendAuthPacket(); _socket!.listen((data) { - debugPrint('📥 [TCP] 收到原始数据:${data.length} 字节, 内容:$data'); + //debugPrint('📥 [TCP] 收到原始数据:${data.length} 字节, 内容:$data'); + _logger.logWithLevel('✅ [TCP] 监听数据...'); // var packets = _decoder.decode(data); // debugPrint('📦 [TCP] 解码成功,包数量:${packets.length}'); //for (var packet in packets) { @@ -84,40 +94,48 @@ class TcpClient { // } try { var packets = _decoder.decode(data); - debugPrint('📦 [TCP] 解码成功,包数量:${packets.length}'); + //debugPrint('📦 [TCP] 解码成功,包数量:${packets.length}'); + _logger.logWithLevel('✅ [TCP] 解码成功,包数量:${packets.length}'); for (var packet in packets) { if (!_controller.isClosed) { _controller.add(packet); - debugPrint('➡️ [TCP] 已分发 CMD: 0x${packet.command.toRadixString(16)}'); + //debugPrint('➡️ [TCP] 已分发 CMD: 0x${packet.command.toRadixString(16)}'); + _logger.logWithLevel('✅ [TCP] 已分发 CMD: 0x${packet.command.toRadixString(16)}'); } if (packet.command == 0xFF) { - debugPrint('收到服务端心跳,自动回复...'); + //debugPrint('收到服务端心跳,自动回复...'); + _logger.logWithLevel('✅ [TCP] 收到服务端心跳,自动回复...'); sendHeartbeat(); // 回复 AB AA FF AA AB } if (packet.command == 0x03) { - debugPrint('⚠️ 收到认证响应:${packet.payload}'); + // debugPrint('⚠️ 收到认证响应:${packet.payload}'); + _logger.logWithLevel('⚠️ 收到认证响应:${packet.payload}'); // 解析 payload 看是否有错误信息 } } } catch (e, stackTrace) { debugPrint('❌ [TCP] 解码数据时发生异常:$e\n$stackTrace'); // 🔥 捕获解码异常 + _logger.logWithLevel('❌ [TCP] 解码数据时发生异常:$e\n$stackTrace'); } }, onDone: (){ // TODO: 断线重连 - debugPrint('来到断线重连!'); + // debugPrint('来到断线重连!'); if (!_isSwitching) { - debugPrint('onDone❌ [TCP] 连接已断开!'); + //debugPrint('onDone❌ [TCP] 连接已断开!'); + _logger.logWithLevel('❌ [TCP] 连接已断开!'); _handleDisconnect(); } _isSwitching = false; // 重置标志,以免影响下次 }, onError: (e) { - debugPrint('来到断线重连!error'); + //debugPrint('来到断线重连!error'); + _logger.logWithLevel('❌ [TCP] 发生错误:$e'); if (!_isSwitching) { - debugPrint('❌ [TCP] 发生错误:$e'); + //debugPrint('❌ [TCP] 发生错误:$e'); + _logger.logWithLevel('❌ [TCP] 发生错误:$e'); _handleDisconnect(); } // 统一走重连逻辑,保护 Controller 不被关闭 _isSwitching = false; // 重置标志,以免影响下次 @@ -143,15 +161,18 @@ class TcpClient { if (isUserSwitch) return; if (_reconnectTimer != null) return; - debugPrint('⏳ 调度重连:Host=${_lastHost}, Port=${_lastPort}'); // ✅ 检查 Host/Port 是否为空 + // debugPrint('⏳ 调度重连:Host=${_lastHost}, Port=${_lastPort}'); // ✅ 检查 Host/Port 是否为空 + _logger.logWithLevel('⏳ 调度重连:Host=${_lastHost}, Port=${_lastPort}'); if (_lastHost == null || _lastPort == null) { - debugPrint('❌ 无法重连:Host 或 Port 为空!'); + //debugPrint('❌ 无法重连:Host 或 Port 为空!'); + _logger.logWithLevel('❌ 无法重连:Host 或 Port 为空!'); return; } _reconnectTimer = Timer(const Duration(seconds: 5), () { _reconnectTimer = null; - debugPrint('⏰ 定时器触发,开始执行重连...'); + //debugPrint('⏰ 定时器触发,开始执行重连...'); + _logger.logWithLevel('⏰ 定时器触发,开始执行重连...'); connect(host: _lastHost!, port: _lastPort!); }); await _sendAuthPacket(); @@ -164,13 +185,15 @@ class TcpClient { debugPrint('⏳ 被动调度重连:Host=${_lastHost}, Port=${_lastPort}'); // ✅ 检查 Host/Port 是否为空 if (_lastHost == null || _lastPort == null) { - debugPrint('❌ 无法重连:Host 或 Port 为空!'); + // debugPrint('❌ 无法重连:Host 或 Port 为空!'); + _logger.logWithLevel('❌ 无法重连:Host 或 Port 为空!'); return; } _reconnectTimer = Timer(const Duration(seconds: 5), () { _reconnectTimer = null; - debugPrint('⏰ 被动-定时器触发,开始执行重连...'); + //debugPrint('⏰ 被动-定时器触发,开始执行重连...'); + _logger.logWithLevel('⏰ 被动-定时器触发,开始执行重连...'); connectBySwitch(host: _lastHost!, port: _lastPort!, deviceName: devname); }); await _sendAuthPacketBySwitch(devname); @@ -218,7 +241,8 @@ class TcpClient { // 新增:启动心跳(每 4 秒发送一次 0xFF 指令) void startHeartbeat({Duration interval = const Duration(seconds: 4)}) { if (_heartbeatTimer != null) return; // 防止重复启动 - debugPrint('收到服务端心跳,自动回复...'); + //debugPrint('收到服务端心跳,自动回复...'); + _logger.logWithLevel('✅ [TCP] 收到服务端心跳,自动回复...'); _heartbeatTimer = Timer.periodic(interval, (_) { // 发送心跳帧:AB AA FF 00 00 AA AB(与 sendRaw 一致) //sendRaw(0xFF, []); @@ -246,7 +270,8 @@ class TcpClient { // // } void disconnect() { - debugPrint('🛑 [TCP] 主动断开连接...'); + //debugPrint('🛑 [TCP] 主动断开连接...'); + _logger.logWithLevel('🛑 [TCP] 主动断开连接...'); // 1. 停止心跳 stopHeartbeat(); @@ -259,24 +284,28 @@ class TcpClient { if (_socket != null) { _socket!.destroy(); _socket = null; - debugPrint('✅ [TCP] Socket 已物理销毁'); + //debugPrint('✅ [TCP] Socket 已物理销毁'); + _logger.logWithLevel('✅ [TCP] Socket 已物理销毁'); } // ❌ 绝对不要关闭 _controller!否则数据流断裂,重连后收不到数据 // _controller.close(); - debugPrint('✅ [TCP] 连接已断开,等待手动重连'); + // debugPrint('✅ [TCP] 连接已断开,等待手动重连'); + _logger.logWithLevel('✅ [TCP] 断开连接成功'); } void sendPathPoint(RoutePlanSendEntity routePlanSendEntity) { if (_socket == null) return; final payload = routePlanSendEntity.toBytes(); - print("sendPathPoint-0x01开始发送路径点数据"); + // print("sendPathPoint-0x01开始发送路径点数据"); + _logger.logWithLevel("sendPathPoint-0x01开始发送路径点数据"); //sendRaw(0x01, payload); // 第1种的测试 声明指令结构和类型0x01 为命令类型 sendnew(payload); // 第1种的测试 声明指令结构和类型0x01 为命令类型 // _socket!.add(payload);//第二种的测试 - print("底层发送指令完成"); + //s print("底层发送指令完成"); + _logger.logWithLevel("底层发送指令完成"); } @@ -300,7 +329,8 @@ class TcpClient { // _socket!.add(packet); var counts = routePlanSendEntity.pointCounts; - print("sendDeviceStateChange 底层发送指令完成,数据:$counts"); + //print("sendDeviceStateChange 底层发送指令完成,数据:$counts"); + _logger.logWithLevel("sendDeviceStateChange 底层发送指令完成,数据:$counts"); /// print("📡 发送的完整数据包:${builder.takeBytes()}"); } @@ -311,7 +341,8 @@ class TcpClient { String? username= ""; String? token= ""; final user = await _userStorage.getUser(); - debugPrint('tcp使用用户信息:$user'); + //debugPrint('tcp使用用户信息:$user'); + _logger.log('tcp使用用户信息:$user'); if (user == null || user.token == null) { debugPrint('❌ [TCP] 认证失败:用户未登录或 Token 为空,无法发送认证包'); disconnect(); @@ -320,7 +351,8 @@ class TcpClient { username = user.username; token = user.token; final authString = '$username:app:$token'; - debugPrint('🔑 [TCP] 认证字符串:$authString'); + //debugPrint('🔑 [TCP] 认证字符串:$authString'); + _logger.log('🔑 [TCP] 认证字符串:$authString'); final authBytes = utf8.encode(authString); // 构造包结构:Head(2) + Cmd(1) + Payload(N) + CRC(2) + Foot(2) @@ -340,7 +372,8 @@ class TcpClient { builder.addByte(0xAB); _socket!.add(builder.takeBytes()); - debugPrint('🔑 [TCP] 已发送认证包 (0x03): $authString'); + //debugPrint('🔑 [TCP] 已发送认证包 (0x03): $authString'); + _logger.log('🔑 [TCP] 已发送认证包 (0x03): $authString'); try { // 1. 获取 Either 结果 @@ -352,39 +385,43 @@ class TcpClient { await eitherResult.fold( (failure) { // 处理失败:打印日志或抛出异常 - debugPrint('❌ [AuthTcp] 获取设备列表失败:$failure'); + // debugPrint('❌ [AuthTcp] 获取设备列表失败:$failure'); + _logger.logWithLevel('❌ [AuthTcp] 获取设备列表失败:$failure'); // _sendAuthPacket(); throw Exception('获取设备列表失败:$failure'); }, (devices) async { // 处理成功:devices 现在是真正的 List if (devices.isEmpty) { - debugPrint('⚠️ [AuthTcp] 当前用户无可用设备,跳过切换步骤'); - + // debugPrint('⚠️ [AuthTcp] 当前用户无可用设备,跳过切换步骤'); + _logger.logWithLevel('⚠️ [AuthTcp] 当前用户无可用设备,跳过切换步骤'); return; } // 取第一个设备 final DeviceEntity targetDevice = devices.first; - debugPrint('📱 [AuthTcp] 准备切换至默认设备:${targetDevice.deviceName}'); - + // debugPrint('📱 [AuthTcp] 准备切换至默认设备:${targetDevice.deviceName}'); +_logger.logWithLevel('📱 [AuthTcp] 准备切换至默认设备:${targetDevice.deviceName}'); // 切换设备 final switchResult = await switchDeviceUseCase.deviceRepository.switchDevice("app",targetDevice.deviceName); await switchResult.fold( (failure) { - debugPrint('❌ [AuthTcp] 切换设备失败:$failure'); + // debugPrint('❌ [AuthTcp] 切换设备失败:$failure'); + _logger .logWithLevel('❌ [AuthTcp] 切换设备失败:$failure'); // _sendAuthPacket(); throw Exception('切换设备失败:$failure'); }, (success) { - debugPrint('✅ [AuthTcp] 设备切换成功,服务端应开始推送数据'); + // debugPrint('✅ [AuthTcp] 设备切换成功,服务端应开始推送数据'); + _logger.logWithLevel('✅ [AuthTcp] 设备切换成功,服务端应开始推送数据'); }, ); }, ); } catch (e) { - debugPrint('❌ [AuthTcp] 设备订阅流程异常:$e'); + // debugPrint('❌ [AuthTcp] 设备订阅流程异常:$e'); + _logger.logWithLevel('❌ [AuthTcp] 设备订阅流程异常:$e'); rethrow; } } @@ -396,7 +433,8 @@ class TcpClient { Future connectBySwitch({required String host, required int port, required String deviceName}) async { isUserSwitch=true; - debugPrint('🔌被动 [TCP] 开始连接:$host:$port'); // ✅ 必须看到这条 + // debugPrint('🔌被动 [TCP] 开始连接:$host:$port'); // ✅ 必须看到这条 + _logger.logWithLevel('🔌被动 [TCP] 开始连接:$host:$port'); _lastHost = host; _lastPort = port; @@ -411,10 +449,12 @@ class TcpClient { port, timeout: const Duration(seconds: 5), ); - debugPrint('✅ 被动[TCP] 连接成功!'); // ✅ 必须看到这条 + // debugPrint('✅ 被动[TCP] 连接成功!'); // ✅ 必须看到这条 + _logger.logWithLevel('✅ 被动[TCP] 连接成功!'); _socket!.listen((data) { - debugPrint('📥 被动[TCP] 收到原始数据:${data.length} 字节, 内容:$data'); + // debugPrint('📥 被动[TCP] 收到原始数据:${data.length} 字节, 内容:$data'); + _logger.logWithLevel('📥 被动[TCP] 收到原始数据:${data.length} 字节, 内容:$data'); // var packets = _decoder.decode(data); // debugPrint('📦 [TCP] 解码成功,包数量:${packets.length}'); //for (var packet in packets) { @@ -428,40 +468,49 @@ class TcpClient { // } try { var packets = _decoder.decode(data); - debugPrint('📦 被动[TCP] 解码成功,包数量:${packets.length}'); + //debugPrint('📦 被动[TCP] 解码成功,包数量:${packets.length}'); + _logger.logWithLevel('📦 被动[TCP] 解码成功,包数量:${packets.length}'); for (var packet in packets) { if (!_controller.isClosed) { _controller.add(packet); - debugPrint('➡️被动 [TCP] 已分发 CMD: 0x${packet.command.toRadixString(16)}'); + //debugPrint('➡️被动 [TCP] 已分发 CMD: 0x${packet.command.toRadixString(16)}'); + _logger.logWithLevel('➡️被动 [TCP] 已分发 CMD: 0x${packet.command.toRadixString(16)}'); } if (packet.command == 0xFF) { - debugPrint('收到服务端心跳,自动回复...'); + //debugPrint('收到服务端心跳,自动回复...'); + _logger.logWithLevel('✅ [TCP] 收到服务端心跳,自动回复...'); + // sendHeartbeat(); // 回复 AB AA FF AA AB } if (packet.command == 0x03) { - debugPrint('⚠️ 收到认证响应:${packet.payload}'); + //debugPrint('⚠️ 收到认证响应:${packet.payload}'); + _logger.logWithLevel('⚠️ 收到认证响应:${packet.payload}'); // 解析 payload 看是否有错误信息 } } } catch (e, stackTrace) { - debugPrint('❌ 被动[TCP] 解码数据时发生异常:$e\n$stackTrace'); // 🔥 捕获解码异常 + //debugPrint('❌ 被动[TCP] 解码数据时发生异常:$e\n$stackTrace'); // 🔥 捕获解码异常 + _logger.logWithLevel('❌ 被动[TCP] 解码数据时发生异常:$e\n$stackTrace'); } }, onDone: (){ // TODO: 断线重连 - debugPrint('onDone❌ 被动[TCP] 连接已断开!'); + // debugPrint('onDone❌ 被动[TCP] 连接已断开!'); + _logger.logWithLevel('onDone❌ 被动[TCP] 连接已断开!'); if (!_isSwitching) { _handleDisconnectBySwitch(deviceName); } else { - debugPrint('🚫 [TCP] 检测到切换过程中的断开,忽略重连调度,防止死循环'); + //debugPrint('🚫 [TCP] 检测到切换过程中的断开,忽略重连调度,防止死循环'); + _logger.logWithLevel('🚫 [TCP] 检测到切换过程中的断开,忽略重连调度,防止死循环'); // 可选:如果是因为切换导致的断开,这里不需要做任何事,因为主流程已经在运行了 // 但为了安全,可以重置一下标志位,防止后续逻辑误判 _isSwitching = false; } }, onError: (e) { - debugPrint('❌ 被动[TCP] 发生错误:$e'); + // debugPrint('❌ 被动[TCP] 发生错误:$e'); + _logger.logWithLevel('❌ 被动[TCP] 发生错误:$e'); _handleDisconnectBySwitch(deviceName); // 统一走重连逻辑,保护 Controller 不被关闭 }, ); @@ -478,16 +527,19 @@ class TcpClient { String? token= ""; final user = await _userStorage.getUser(); deviceName= deviceName; - debugPrint('tcp被动切换认证:$user'); + // debugPrint('tcp被动切换认证:$user'); + _logger.logWithLevel('tcp被动切换认证:$user'); if (user == null || user.token == null) { - debugPrint('❌ 被动[TCP] 认证失败:用户未登录或 Token 为空,无法发送认证包'); + // debugPrint('❌ 被动[TCP] 认证失败:用户未登录或 Token 为空,无法发送认证包'); + _logger.logWithLevel('❌ 被动[TCP] 认证失败:用户未登录或 Token 为空,无法发送认证包'); disconnect(); return; // 直接返回,不要发送无效包 } username = user.username; token = user.token; final authString = '$username:app:$token'; - debugPrint('🔑被动[TCP] 认证字符串:$authString'); + // debugPrint('🔑被动[TCP] 认证字符串:$authString'); + _logger.logWithLevel('🔑被动[TCP] 认证字符串:$authString'); final authBytes = utf8.encode(authString); // 构造包结构:Head(2) + Cmd(1) + Payload(N) + CRC(2) + Foot(2) @@ -507,13 +559,15 @@ class TcpClient { builder.addByte(0xAB); _socket!.add(builder.takeBytes()); - debugPrint('🔑 被动[TCP] 已发送认证包 (0x03): $authString'); + //debugPrint('🔑 被动[TCP] 已发送认证包 (0x03): $authString'); + _logger.logWithLevel('🔑 被动[TCP] 已发送认证包 (0x03): $authString'); try { // 1. 获取 Either 结果 await switchDeviceUseCase.deviceRepository.switchDevice("app",deviceName); } catch (e) { - debugPrint('❌ 被动[AuthTcp] 设备订阅流程异常:$e'); + //debugPrint('❌ 被动[AuthTcp] 设备订阅流程异常:$e'); + _logger.logWithLevel('❌ 被动[AuthTcp] 设备订阅流程异常:$e'); rethrow; }