This commit is contained in:
dzc committed 2026-09-09 20:22:59 +08:00
1 parent a461b0fda3
commit 2e0036af45
5 files changed
+108 -15

No files matched your search

+10 -2
View File
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'package:common_utils/common_utils.dart';
@@ -129,6 +130,15 @@ class AppMqTool {
logger.e("|$_tag|定餐广播执行错误orgStr|$orgStr|error|$e|stack|$stack|");
}
return;
case MqtActionEnum.PULL_TERMINAL_LOG:
mqUpdateEventBus.fire(MqtActionEnum.PULL_TERMINAL_LOG);
// MQTT 回调不能等待文件扫描和上传,任务会在支付/识别结束后的安全窗口异步执行。
unawaited(SyncCheckTool.instance.trigger(
ScheduledTaskType.terminalLogUpload,
currentLogOnly: true,
triggerType: ScheduledTaskTriggerType.mqtt,
));
return;
case MqtActionEnum.FACE:
return;
// final msg = MqttInvoiceMsg.fromJson(json.decode(orgStr));
@@ -152,8 +162,6 @@ class AppMqTool {
// );
// mqUpdateEventBus.fire(MqtActionEnum.FACE);
// break;
default:
break;
}
}
@@ -40,6 +40,7 @@ class AppControl extends GetxController {
AppNetworkTool.closeListenNetwork();
TtsManage.dispose();
SyncCheckTool.instance.dispose();
TerminalHeartbeatTool.stop();
}
Future<void> initAsync() async {
@@ -57,6 +58,8 @@ class AppControl extends GetxController {
await TtsManage.initialize();
await Future.delayed(const Duration(milliseconds: 500));
SyncCheckTool.instance.startAll();
// 服务端按 180 秒心跳阈值判定设备在线,启动后必须开启周期上报,未绑定设备时上报内部会安全跳过。
TerminalHeartbeatTool.start();
Get.offAllNamed(RouteNames.login);
}
}
+80 -11
View File
@@ -50,13 +50,33 @@ class MqManager {
MqManager.mqttClient = null;
}
MqManager.state = MqttConnectionState.disconnected;
connectionFailureReason = null;
}
/// 打印实际用于连接的参数,便于与外部MQTT工具比对定位notAuthorized;密码只展示长度与首尾几位。
static void _logConnectParams(
String scene,
SysSetting config, {
required String clientId,
required String host,
required int port,
}) {
final password = config.mqPassword ?? '';
final maskedPassword = password.length < 6
? "*(len:${password.length})"
: "${password.substring(0, 3)}***(len:${password.length})${password.substring(password.length - 3)}";
logger.i(
"|$_tag|连接参数|scene:$scene|host:$host|port:$port|clientId:$clientId"
"|username:${config.mqUsername}|password:$maskedPassword"
"|tls:${port == 8883}|protocol:MQTT/3.1.1|",
);
}
static Future<void> initMqtt() async {
// 获取配置
final config = await validate();
if (ObjectUtil.isEmpty(config!)) return;
final port = int.tryParse(config.mqSocketPort!);
if (ObjectUtil.isEmpty(config)) return;
final port = int.tryParse(config!.mqSocketPort!);
if (ObjectUtil.isEmpty(port)) return;
final client = MqttServerClient.withPort(
config.mqSocketAddress!,
@@ -87,6 +107,13 @@ class MqManager {
MqttConnectMessage().withProtocolName("MQTT").withProtocolVersion(4);
client.connectionMessage = connMessage;
_logConnectParams(
"初始化",
config,
clientId: client.clientIdentifier,
host: client.server,
port: port,
);
try {
final state = await client.connect(config.mqUsername, config.mqPassword);
if (ObjectUtil.isNotEmpty(state)) {
@@ -96,6 +123,7 @@ class MqManager {
}
}
} catch (e) {
connectionFailureReason = "mqtt连接失败:$e";
logger.e("|$_tag|mqtt连接失败error:|$e|");
}
}
@@ -103,21 +131,61 @@ class MqManager {
static Future<void> refresh() async {
final config = await validate();
if (ObjectUtil.isEmpty(config)) {
connectionFailureReason = "mq参数校验不通过,本地配置缺少连接必要字段";
logger.e("|$_tag||刷新mq|错误mq参数校验不通过");
return;
}
final port = int.tryParse(config!.mqSocketPort!);
if (ObjectUtil.isEmpty(port)) {
connectionFailureReason = "mq端口非法:${config.mqSocketPort}";
logger.e("|$_tag||刷新mq|错误mq端口非法|port:${config.mqSocketPort}|");
return;
}
if (ObjectUtil.isEmpty(mqttClient)) {
await initMqtt();
} else if (MqManager.state != MqttConnectionState.connected) {
final res = await mqttClient!.connect(
config!.mqUsername,
config.mqPassword,
);
if (res != null && res.state != MqManager.state) {
MqManager.state = res.state;
}
} else {
} else if (MqManager.state == MqttConnectionState.connected) {
logger.e("|$_tag||刷新mq|错误mq已连接");
} else {
final client = mqttClient!;
// 旧client实例的clientId与地址在创建时已固化,配置变化后继续复用会拿旧clientId配新账密,被broker以notAuthorized拒绝。
final stale =
client.clientIdentifier != config.mqClientId ||
client.server != config.mqSocketAddress ||
client.port != port;
if (stale) {
logger.w(
"|$_tag||刷新mq|mq连接参数已变化,重建client"
"|old:${client.server}:${client.port}/${client.clientIdentifier}"
"|new:${config.mqSocketAddress}:$port/${config.mqClientId}|",
);
await closeMqtt();
await initMqtt();
return;
}
_logConnectParams(
"重连",
config,
clientId: client.clientIdentifier,
host: client.server,
port: client.port,
);
try {
final res = await client.connect(
config.mqUsername,
config.mqPassword,
);
if (res != null && res.state != MqManager.state) {
MqManager.state = res.state;
}
if (MqManager.state == MqttConnectionState.connected) {
connectionFailureReason = null;
} else {
connectionFailureReason = "mqtt连接异常,当前状态:${MqManager.state}";
}
} catch (e) {
connectionFailureReason = "mqtt连接失败:$e";
rethrow;
}
}
}
@@ -135,6 +203,7 @@ class MqManager {
static void _onConnected() async {
logger.w("|$_tag|mqtt连接成功");
connectionFailureReason = null;
final config = await AppSettingTool.getSysSetting();
if (ObjectUtil.isNotEmpty(config)) {
config.mqSyncTime = DateTime.now();