优化掉tcp中print打印影响性能的代码用日志对象代替打印
This commit is contained in:
@@ -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<ILoggerService>();
|
||||
|
||||
|
||||
// 🔥 新增: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<String> 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<Map<String, dynamic>> 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<RawPacket> onPathPlanningResponse() {
|
||||
final devicesCubit = sl<DevicesCubit>();
|
||||
|
||||
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<DeviceAddPathPointModel>);
|
||||
@@ -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>();
|
||||
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;
|
||||
|
||||
@@ -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<ILoggerService>();
|
||||
|
||||
|
||||
// 新增:心跳定时器
|
||||
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<void> 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<DeviceEntity>
|
||||
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<void> 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user