diff --git a/lib/login/login/starLock_login_page.dart b/lib/login/login/starLock_login_page.dart index 5b266f22..3e078688 100755 --- a/lib/login/login/starLock_login_page.dart +++ b/lib/login/login/starLock_login_page.dart @@ -36,6 +36,7 @@ class _StarLockLoginPageState extends State { WidgetsBinding.instance.addPostFrameCallback((_) async { AppFirstEnterHandle().getAppFirstEnter(isAgreePrivacy); }); + StartChartManage().init(); } @override @@ -233,12 +234,6 @@ class _StarLockLoginPageState extends State { } } : null)), - SubmitBtn( - btnName: '初始化星图服务', - onClick: () async { - await StartChartManage().init(); - }, - ), SubmitBtn( btnName: '发送回声测试消息', onClick: () { @@ -251,7 +246,7 @@ class _StarLockLoginPageState extends State { onClick: () { StartChartManage().sendGatewayResetMessage( ToPeerId: '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH', - gatewayId: 1, + gatewayId: 1000000000, ); }, ), diff --git a/lib/talk/startChart/command/message_command.dart b/lib/talk/startChart/command/message_command.dart index 81252032..76678044 100644 --- a/lib/talk/startChart/command/message_command.dart +++ b/lib/talk/startChart/command/message_command.dart @@ -79,11 +79,13 @@ class MessageCommand { required String ToPeerId, required int time, }) { + // 构建荷载 final gatewayResetReq = GatewayResetReq( iD: gatewayId, time: time, ); - final payloadLength = gatewayResetReq.writeToBuffer().length; + // 构建荷载参数 + final payload = gatewayResetReq.writeToBuffer(); ScpMessage message = ScpMessage( ProtocolFlag: ProtocolFlagConstant.scp01, MessageType: MessageTypeConstant.Req, @@ -92,9 +94,9 @@ class MessageCommand { SpIndex: 0, FromPeerId: FromPeerId, ToPeerId: ToPeerId, - Payload: gatewayResetReq, + Payload: payload, PayloadCRC: 55230, - PayloadLength: payloadLength, + PayloadLength: payload.length, PayloadType: PayloadTypeConstant.gatewayReset, ); String serializedBytesString = message.serialize(); diff --git a/lib/talk/startChart/constant/udp_constant.dart b/lib/talk/startChart/constant/udp_constant.dart new file mode 100644 index 00000000..39c6e524 --- /dev/null +++ b/lib/talk/startChart/constant/udp_constant.dart @@ -0,0 +1,5 @@ +class UdpConstant{ + // generic成功响应 + static const int genericRespSuccessCode = 0; + static const String genericRespSuccessMsg = 'ok'; +} \ No newline at end of file diff --git a/lib/talk/startChart/entity/scp_message.dart b/lib/talk/startChart/entity/scp_message.dart index ccbcd5db..a822ca4c 100644 --- a/lib/talk/startChart/entity/scp_message.dart +++ b/lib/talk/startChart/entity/scp_message.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:crc32_checksum/crc32_checksum.dart'; import 'package:crypto/crypto.dart'; +import 'package:get/get.dart'; import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart'; import 'package:star_lock/talk/startChart/entity/heartbeat_response.dart'; @@ -140,6 +141,9 @@ class ScpMessage { // Payload (字符串,转换为字节) if (Payload != null && Payload is String) { bytes.addAll(utf8.encode(Payload!)); + } else { + // 如果不是字符串则需要外部转为字节数组,这里直接添加 + bytes.addAll(Payload); } // 转16进制字符串 @@ -277,65 +281,76 @@ class ScpMessage { int? offset, int? PayloadLength, }) { - switch (payloadType) { - case PayloadTypeConstant.goOnline: - // 上线 - LoginResponse loginResp = LoginResponse.fromBytes(byte); - return loginResp; - case PayloadTypeConstant.heartbeat: - // 心跳 - HeartbeatResponse heartbeatResponse = HeartbeatResponse.fromBytes(byte); - return heartbeatResponse; - case PayloadTypeConstant.echoTest: - // 回声测试 - String payload = utf8.decode(byte); - return payload; - case PayloadTypeConstant.gatewayReset: - // 初始化网关 - final GatewayResetResp gatewayResetResp = - GatewayResetResp.fromBuffer(byte); - return gatewayResetResp; - case PayloadTypeConstant.callRequest: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - case PayloadTypeConstant.talkAccept: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - case PayloadTypeConstant.gatewayTransfer: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - case PayloadTypeConstant.blePassthrough: - final BleResp bleResp = BleResp.fromBuffer(byte); - return bleResp; - case PayloadTypeConstant.remoteUnlock: - final RemoteUnlockResp remoteUnlockResp = - RemoteUnlockResp.fromBuffer(byte); - return remoteUnlockResp; - case PayloadTypeConstant.talkReceiverTransfer: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - case PayloadTypeConstant.talkPush: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - case PayloadTypeConstant.talkReject: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - case PayloadTypeConstant.talkPing: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - case PayloadTypeConstant.talkExpect: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - case PayloadTypeConstant.talkData: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - case PayloadTypeConstant.talkHangup: - final GenericResp genericResp = GenericResp.fromBuffer(byte); - return genericResp; - default: - print('❌未知的payloadType类型,按照字符串解析'); - String payload = utf8.decode(byte); - return payload; + try { + switch (payloadType) { + case PayloadTypeConstant.goOnline: + // 上线 + LoginResponse loginResp = LoginResponse.fromBytes(byte); + return loginResp; + case PayloadTypeConstant.heartbeat: + // 心跳 + HeartbeatResponse heartbeatResponse = + HeartbeatResponse.fromBytes(byte); + return heartbeatResponse; + case PayloadTypeConstant.echoTest: + // 回声测试 + String payload = utf8.decode(byte); + return payload; + case PayloadTypeConstant.gatewayReset: + // 初始化网关 + final GatewayResetResp gatewayResetResp = + GatewayResetResp.fromBuffer(byte); + return gatewayResetResp; + case PayloadTypeConstant.callRequest: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + case PayloadTypeConstant.talkAccept: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + case PayloadTypeConstant.gatewayTransfer: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + case PayloadTypeConstant.blePassthrough: + final BleResp bleResp = BleResp.fromBuffer(byte); + return bleResp; + case PayloadTypeConstant.remoteUnlock: + final RemoteUnlockResp remoteUnlockResp = + RemoteUnlockResp.fromBuffer(byte); + return remoteUnlockResp; + case PayloadTypeConstant.talkReceiverTransfer: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + case PayloadTypeConstant.talkPush: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + case PayloadTypeConstant.talkReject: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + case PayloadTypeConstant.talkPing: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + case PayloadTypeConstant.talkExpect: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + case PayloadTypeConstant.talkData: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + case PayloadTypeConstant.talkHangup: + final GenericResp genericResp = GenericResp.fromBuffer(byte); + return genericResp; + default: + print('❌未知的payloadType类型,按照字符串解析'); + String payload = utf8.decode(byte); + return payload; + } + } catch (e) { + _log(text: '❌反序列化udp数据时遇到错误----》$e'); + String payload = utf8.decode(byte); + return payload; } } + + static void _log({required String text}) { + AppLog.log('=====${text}'); + } } diff --git a/lib/talk/startChart/handle/impl/udp_call_request_handler.dart b/lib/talk/startChart/handle/impl/udp_call_request_handler.dart new file mode 100644 index 00000000..1af828b6 --- /dev/null +++ b/lib/talk/startChart/handle/impl/udp_call_request_handler.dart @@ -0,0 +1,24 @@ +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/appRouters.dart'; +import 'package:star_lock/talk/startChart/entity/scp_message.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart'; +import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart'; +import 'package:star_lock/talk/startChart/proto/generic.pb.dart'; + +import '../../start_chart_manage.dart'; + +class UdpCallRequestHandler extends ScpMessageBaseHandle implements ScpMessageHandler { + @override + void handle(ScpMessage scpMessage) { + final GenericResp genericResp = scpMessage.Payload; + if (checkGenericRespSuccess(genericResp)) { + // TODO 收到呼叫请求,跳转到接听页面 + Get.toNamed( + Routers.lockMonitoringPage, + arguments: {'lockId': '111'}, + ); + } + } +} diff --git a/lib/talk/startChart/handle/impl/udp_echo_test_handler.dart b/lib/talk/startChart/handle/impl/udp_echo_test_handler.dart new file mode 100644 index 00000000..bb7f9a3b --- /dev/null +++ b/lib/talk/startChart/handle/impl/udp_echo_test_handler.dart @@ -0,0 +1,14 @@ +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/talk/startChart/entity/scp_message.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart'; + +import '../../start_chart_manage.dart'; + +class UdpEchoTestHandler extends ScpMessageBaseHandle implements ScpMessageHandler { + @override + void handle(ScpMessage scpMessage) { + EasyLoading.showToast(scpMessage.Payload, duration: 2000.milliseconds); + } +} diff --git a/lib/talk/startChart/handle/impl/udp_gateway_reset_handler.dart b/lib/talk/startChart/handle/impl/udp_gateway_reset_handler.dart new file mode 100644 index 00000000..730a0aab --- /dev/null +++ b/lib/talk/startChart/handle/impl/udp_gateway_reset_handler.dart @@ -0,0 +1,19 @@ +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/talk/startChart/entity/scp_message.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart'; +import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart'; + +import '../../start_chart_manage.dart'; + +class UdpGateWayResetHandler extends ScpMessageBaseHandle implements ScpMessageHandler { + @override + void handle(ScpMessage scpMessage) { + final GatewayResetResp gatewayResetResp = scpMessage.Payload; + final status = gatewayResetResp.status; + if (status != null && status == GatewayResetResp_StatusE.OK) { + // TODO 网关初始化成功 + } + } +} diff --git a/lib/talk/startChart/handle/impl/udp_go_online_handler.dart b/lib/talk/startChart/handle/impl/udp_go_online_handler.dart new file mode 100644 index 00000000..5cb6b5f4 --- /dev/null +++ b/lib/talk/startChart/handle/impl/udp_go_online_handler.dart @@ -0,0 +1,27 @@ +import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart'; +import 'package:star_lock/talk/startChart/entity/login_response.dart'; +import 'package:star_lock/talk/startChart/entity/scp_message.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart'; + +import '../../start_chart_manage.dart'; + +class UdpGoOnlineHandler extends ScpMessageBaseHandle + implements ScpMessageHandler { + @override + void handle(ScpMessage scpMessage) { + final startChartManage = StartChartManage(); + final LoginResponse loginResponse = scpMessage.Payload; + final responseType = loginResponse.responseType; + if (responseType != null && + responseType == PayloadTypeConstant.loginSuccessResponse) { + startChartManage.isOnlineStartChartServer = true; + // 上线成功,停止重发 + startChartManage.stopReStartOnlineStartChartServer(); + log(text: '星图登录成功'); + } else { + // 上线失败,重发 + startChartManage.reStartOnlineStartChartServer(); + } + } +} diff --git a/lib/talk/startChart/handle/impl/udp_heart_beat_handler.dart b/lib/talk/startChart/handle/impl/udp_heart_beat_handler.dart new file mode 100644 index 00000000..fb894e7a --- /dev/null +++ b/lib/talk/startChart/handle/impl/udp_heart_beat_handler.dart @@ -0,0 +1,26 @@ +import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart'; +import 'package:star_lock/talk/startChart/entity/heartbeat_response.dart'; +import 'package:star_lock/talk/startChart/entity/login_response.dart'; +import 'package:star_lock/talk/startChart/entity/scp_message.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart'; + +import '../../start_chart_manage.dart'; + +class UdpHeartBeatHandler extends ScpMessageBaseHandle implements ScpMessageHandler { + @override + void handle(ScpMessage scpMessage) { + final startChartManage = StartChartManage(); + final HeartbeatResponse heartbeatResponse = scpMessage.Payload; + final statusCode = heartbeatResponse.statusCode; + if (statusCode != null && + statusCode != PayloadTypeConstant.heartHeatSuccessResponse) { + // 心跳响应失败,重新上线 + startChartManage.reStartOnlineStartChartServer(); + } + startChartManage.heartbeatIntervalTime = + heartbeatResponse.nextPingTime ?? 1; + // 修改完间隔之后重新启动发送心跳 + startChartManage.reStartHeartBeat(); + } +} diff --git a/lib/talk/startChart/handle/impl/unknow_payload_type_handler.dart b/lib/talk/startChart/handle/impl/unknow_payload_type_handler.dart new file mode 100644 index 00000000..8dc0ba0e --- /dev/null +++ b/lib/talk/startChart/handle/impl/unknow_payload_type_handler.dart @@ -0,0 +1,11 @@ +import 'package:star_lock/app_settings/app_settings.dart'; +import 'package:star_lock/talk/startChart/entity/scp_message.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart'; + +class UnKnowPayloadTypeHandler extends ScpMessageBaseHandle implements ScpMessageHandler { + @override + void handle(ScpMessage scpMessage) { + AppLog.log('❌未知的payloadType类型'); + } +} diff --git a/lib/talk/startChart/handle/scp_message_base_handle.dart b/lib/talk/startChart/handle/scp_message_base_handle.dart new file mode 100644 index 00000000..acf1b8a7 --- /dev/null +++ b/lib/talk/startChart/handle/scp_message_base_handle.dart @@ -0,0 +1,17 @@ +import 'package:star_lock/app_settings/app_settings.dart'; +import 'package:star_lock/talk/startChart/constant/udp_constant.dart'; +import 'package:star_lock/talk/startChart/proto/generic.pb.dart'; + +class ScpMessageBaseHandle { + bool checkGenericRespSuccess(GenericResp genericResp) { + if (genericResp == null) return false; + final code = genericResp.code; + final message = genericResp.message; + return code == UdpConstant.genericRespSuccessCode && + message == UdpConstant.genericRespSuccessMsg; + } + + void log({required String text}) { + AppLog.log('==========${text}'); + } +} diff --git a/lib/talk/startChart/handle/scp_message_handle.dart b/lib/talk/startChart/handle/scp_message_handle.dart new file mode 100644 index 00000000..e98c9fea --- /dev/null +++ b/lib/talk/startChart/handle/scp_message_handle.dart @@ -0,0 +1,5 @@ +import 'package:star_lock/talk/startChart/entity/scp_message.dart'; + +abstract class ScpMessageHandler { + void handle(ScpMessage scpMessage); +} \ No newline at end of file diff --git a/lib/talk/startChart/handle/scp_message_handler_factory.dart b/lib/talk/startChart/handle/scp_message_handler_factory.dart new file mode 100644 index 00000000..99afe83c --- /dev/null +++ b/lib/talk/startChart/handle/scp_message_handler_factory.dart @@ -0,0 +1,27 @@ +import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart'; +import 'package:star_lock/talk/startChart/handle/impl/udp_call_request_handler.dart'; +import 'package:star_lock/talk/startChart/handle/impl/udp_echo_test_handler.dart'; +import 'package:star_lock/talk/startChart/handle/impl/udp_gateway_reset_handler.dart'; +import 'package:star_lock/talk/startChart/handle/impl/udp_go_online_handler.dart'; +import 'package:star_lock/talk/startChart/handle/impl/udp_heart_beat_handler.dart'; +import 'package:star_lock/talk/startChart/handle/impl/unknow_payload_type_handler.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart'; + +class ScpMessageHandlerFactory { + static ScpMessageHandler createHandler(int payloadType) { + switch (payloadType) { + case PayloadTypeConstant.goOnline: + return UdpGoOnlineHandler(); + case PayloadTypeConstant.heartbeat: + return UdpHeartBeatHandler(); + case PayloadTypeConstant.echoTest: + return UdpEchoTestHandler(); + case PayloadTypeConstant.gatewayReset: + return UdpGateWayResetHandler(); + case PayloadTypeConstant.callRequest: + return UdpCallRequestHandler(); + default: + return UnKnowPayloadTypeHandler(); + } + } +} diff --git a/lib/talk/startChart/start_chart_manage.dart b/lib/talk/startChart/start_chart_manage.dart index 54c0d607..3762a87a 100644 --- a/lib/talk/startChart/start_chart_manage.dart +++ b/lib/talk/startChart/start_chart_manage.dart @@ -7,6 +7,7 @@ import 'package:fast_rsa/fast_rsa.dart' as fastRsa; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; import 'package:pointycastle/export.dart' as pc; +import 'package:star_lock/appRouters.dart'; import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/flavors.dart'; import 'package:star_lock/network/start_chart_api.dart'; @@ -14,12 +15,17 @@ import 'package:star_lock/talk/startChart/command/message_command.dart'; import 'package:star_lock/talk/startChart/constant/ip_constant.dart'; import 'package:star_lock/talk/startChart/constant/listen_addr_type_constant.dart'; import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart'; +import 'package:star_lock/talk/startChart/constant/udp_constant.dart'; import 'package:star_lock/talk/startChart/entity/heartbeat_response.dart'; import 'package:star_lock/talk/startChart/entity/login_response.dart'; import 'package:star_lock/talk/startChart/entity/relay_info_entity.dart'; import 'package:star_lock/talk/startChart/entity/report_information_data.dart'; import 'package:star_lock/talk/startChart/entity/scp_message.dart'; import 'package:star_lock/talk/startChart/entity/star_chart_register_node_entity.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart'; +import 'package:star_lock/talk/startChart/handle/scp_message_handler_factory.dart'; +import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart'; +import 'package:star_lock/talk/startChart/proto/generic.pb.dart'; import 'package:star_lock/tools/deviceInfo_utils.dart'; import 'package:star_lock/tools/storage.dart'; import 'package:uuid/uuid.dart'; @@ -48,7 +54,7 @@ class StartChartManage { final int localPort = 62289; // 本地端口 String localPublicHost = ''; // 本地公网ip地址 - int _heartbeatIntervalTime = 1; // 心跳包间隔时间(s) + int heartbeatIntervalTime = 1; // 心跳包间隔时间(s) Timer? _heartBeatTimer; // 心跳包定时器 bool _heartBeatTimerRunning = false; // 心跳包定时任务发送状态 @@ -58,16 +64,15 @@ class StartChartManage { // echo测试peer对端 final String echoPeerId = '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH'; - bool _isOnlineStartChartServer = false; // 星图是否上线成功 - int _reStartOnlineStartChartServerIntervalTime = 1; // 重新上线星图服务任务间隔(s) - Timer? _reStartOnlineStartChartServerTimer; // 重新上线定时器 - bool _reStartOnlineStartChartServerTimerRunning = false; // 重新上线定时任务发送状态 + bool isOnlineStartChartServer = false; // 星图是否上线成功 + int reStartOnlineStartChartServerIntervalTime = 1; // 重新上线星图服务任务间隔(s) + Timer? reStartOnlineStartChartServerTimer; // 重新上线定时器 String relayPeerId = ''; // 中继peerId // 星图服务初始化 Future init() async { - if (_isOnlineStartChartServer && _udpSocket != null) { + if (isOnlineStartChartServer && _udpSocket != null) { // 如果已经上线就不进行初始化 return; } @@ -134,28 +139,6 @@ class StartChartManage { }); } - // 接收返回的数据 - void _onReceiveData(RawDatagramSocket socket) { - socket.listen((RawSocketEvent event) { - if (event == RawSocketEvent.read) { - Datagram? dg = socket.receive(); - try { - if (dg?.data != null) { - final deserialize = ScpMessage.deserialize(dg!.data); - if (deserialize != null) { - _handleUdpResultData(deserialize); - } - if (deserialize.PayloadType != PayloadTypeConstant.heartbeat) { - _log(text: 'Udp收到结构体数据---》$deserialize'); - } - } - } catch (e) { - _log(text: '❌ Udp result data error ----> $e'); - } - } - }); - } - // 上报信息至发现服务 Future reportInformation() async { _log(text: '上报信息至发现服务'); @@ -168,13 +151,13 @@ class StartChartManage { // 发送心跳消息 _sendHeartbeatMessage(); // 发送送上线消息 - await _reStartOnlineStartChartServer(); + await reStartOnlineStartChartServer(); } } // 发送上线消息 Future _sendOnlineMessage() async { - if (_isOnlineStartChartServer) { + if (isOnlineStartChartServer) { _log(text: '星图已上线,请勿重复发送上线消息'); return; } @@ -194,7 +177,7 @@ class StartChartManage { } _heartBeatTimer ??= Timer.periodic( Duration( - seconds: _heartbeatIntervalTime, + seconds: heartbeatIntervalTime, ), (Timer timer) async { final List message = MessageCommand.heartbeatMessage( @@ -223,27 +206,36 @@ class StartChartManage { ToPeerId: ToPeerId, FromPeerId: FromPeerId, gatewayId: gatewayId, - time: DateTime.now().microsecond ~/ 1000, + time: DateTime.now().millisecondsSinceEpoch ~/ 1000, ); await _sendMessage(message: message); + Get.toNamed( + Routers.lockMonitoringPage, + arguments: {'lockId': '111'}, + ); } // 重新上线 - Future _reStartOnlineStartChartServer() async { - if (_isOnlineStartChartServer) { + Future reStartOnlineStartChartServer() async { + if (isOnlineStartChartServer) { _log(text: '星图已上线,请勿重复发送上线消息'); return; } - _reStartOnlineStartChartServerTimer ??= Timer.periodic( + reStartOnlineStartChartServerTimer ??= Timer.periodic( Duration( - seconds: _reStartOnlineStartChartServerIntervalTime, + seconds: reStartOnlineStartChartServerIntervalTime, ), (Timer timer) async { // 重新发送上线消息 await _sendOnlineMessage(); }, ); - _reStartOnlineStartChartServerTimerRunning = true; + } + + // 重新发送心跳 + void reStartHeartBeat() { + stopHeartbeat(); + _sendHeartbeatMessage(); } // 停止定时发送心跳包 @@ -255,9 +247,8 @@ class StartChartManage { // 停止重新上线 void stopReStartOnlineStartChartServer() { - _reStartOnlineStartChartServerTimer?.cancel(); - _reStartOnlineStartChartServerTimer = null; // 清除定时器引用 - _reStartOnlineStartChartServerTimerRunning = false; + reStartOnlineStartChartServerTimer?.cancel(); + reStartOnlineStartChartServerTimer = null; // 清除定时器引用 } // 发送消息 @@ -341,6 +332,11 @@ class StartChartManage { return data; } + // 解析对端数据 + Future analyzeInformationOtherEnd() async { + await StartChartApi.to.analyzeInformationOtherEnd(peerId: ToPeerId); + } + // 获取本机所有ip地址和中继返回的外网地址 Future> _makeListenAddrDataList() async { final List listenAddrDataList = []; @@ -459,7 +455,7 @@ class StartChartManage { return resultSign ?? ''; } -// 将 32 位时间戳以小端字节序编码为二进制数据 + // 将 32 位时间戳以小端字节序编码为二进制数据 Uint8List encodeTimestampToLittleEndianBytes(int timestamp) { // 创建一个 4 字节的 ByteData 对象 ByteData byteData = ByteData(4); @@ -473,6 +469,7 @@ class StartChartManage { return bytes; } + /// 转换私钥格式 String convertToPemPrivateKey(List privateKeyBytes, {bool isPKCS8 = true}) { // 将字节数组转换为Base64编码的字符串 @@ -531,11 +528,6 @@ class StartChartManage { } } - // 解析对端数据 - Future analyzeInformationOtherEnd() async { - await StartChartApi.to.analyzeInformationOtherEnd(peerId: ToPeerId); - } - // 将十六进制字符串转换为字节数组 List hexToBytes(String hex) { return List.generate(hex.length ~/ 2, @@ -549,6 +541,7 @@ class StartChartManage { ); } + /// 获取公钥 Future getPublicKey() async { // 从缓存中获取星图注册节点信息 final StarChartRegisterNodeEntity? starChartRegisterNodeInfo = @@ -556,6 +549,7 @@ class StartChartManage { return starChartRegisterNodeInfo?.peer?.publicKey ?? ''; } + /// 获取私钥 Future getPrivateKey() async { // 从缓存中获取星图注册节点信息 final StarChartRegisterNodeEntity? starChartRegisterNodeInfo = @@ -563,119 +557,37 @@ class StartChartManage { return starChartRegisterNodeInfo?.peer?.privateKey ?? ''; } + // 接收返回的数据 + void _onReceiveData(RawDatagramSocket socket) { + socket.listen((RawSocketEvent event) { + if (event == RawSocketEvent.read) { + Datagram? dg = socket.receive(); + try { + if (dg?.data != null) { + final deserialize = ScpMessage.deserialize(dg!.data); + if (deserialize != null) { + _handleUdpResultData(deserialize); + } + if (deserialize.PayloadType != PayloadTypeConstant.heartbeat) { + _log(text: 'Udp收到结构体数据---》$deserialize'); + } + } + } catch (e) { + _log(text: '❌ Udp result data error ----> $e'); + } + } + }); + } + // 处理udp返回的数据 void _handleUdpResultData(ScpMessage scpMessage) { final int payloadType = scpMessage.PayloadType ?? 0; - switch (payloadType) { - case PayloadTypeConstant.goOnline: - _handleUdpGoOnlineResultData(scpMessage); - break; - case PayloadTypeConstant.heartbeat: - _handleUdpHeartBeatResultData(scpMessage); - break; - case PayloadTypeConstant.echoTest: - _handleUdpEchoTestResultData(scpMessage); - break; - case PayloadTypeConstant.gatewayReset: - // TODO: 处理网关初始化消息 - print('Handling Gateway Reset message.'); - break; - - case PayloadTypeConstant.callRequest: - // TODO: 处理收到呼叫请求消息 - print('Handling Call Request message.'); - break; - - case PayloadTypeConstant.talkAccept: - // TODO: 处理同意接听消息 - print('Handling Talk Accept message.'); - break; - - case PayloadTypeConstant.gatewayTransfer: - // TODO: 处理网关转移消息 - print('Handling Gateway Transfer message.'); - break; - - case PayloadTypeConstant.blePassthrough: - // TODO: 处理蓝牙透传消息 - print('Handling BLE Passthrough message.'); - break; - - case PayloadTypeConstant.remoteUnlock: - // TODO: 处理远程开锁消息 - print('Handling Remote Unlock message.'); - break; - - case PayloadTypeConstant.talkReceiverTransfer: - // TODO: 处理对讲接听者转移消息 - print('Handling Talk Receiver Transfer message.'); - break; - - case PayloadTypeConstant.talkPush: - // TODO: 处理委托推送消息 - print('Handling Talk Push message.'); - break; - - case PayloadTypeConstant.talkReject: - // TODO: 处理拒绝接听消息 - print('Handling Talk Reject message.'); - break; - - case PayloadTypeConstant.talkPing: - // TODO: 处理呼叫保持消息 - print('Handling Talk Ping message.'); - break; - - case PayloadTypeConstant.talkExpect: - // TODO: 处理预期接收消息 - print('Handling Talk Expect message.'); - break; - - case PayloadTypeConstant.talkData: - // TODO: 处理音视频数据消息 - print('Handling Talk Data message.'); - break; - - case PayloadTypeConstant.talkHangup: - // TODO: 处理通话中挂断消息 - print('Handling Talk Hangup message.'); - break; - default: - _log(text: '❌未知的payloadType类型'); - break; + try { + final ScpMessageHandler handler = + ScpMessageHandlerFactory.createHandler(payloadType); + handler.handle(scpMessage); + } catch (e) { + _log(text: '❌ _handleUdpResultData 处理udp返回数据时遇到错误---> $e'); } } - - /// 处理上线命令udp返回的数据 - void _handleUdpGoOnlineResultData(ScpMessage scpMessage) { - final LoginResponse loginResponse = scpMessage.Payload; - final responseType = loginResponse.responseType; - if (responseType != null && - responseType == PayloadTypeConstant.loginSuccessResponse) { - _log(text: '星图登录成功'); - _isOnlineStartChartServer = true; - // 上线成功,停止重发 - stopReStartOnlineStartChartServer(); - } else { - // 上线失败,重发 - _reStartOnlineStartChartServer(); - } - } - - /// 处理心跳命令udp返回的数据 - void _handleUdpHeartBeatResultData(ScpMessage scpMessage) { - final HeartbeatResponse heartbeatResponse = scpMessage.Payload; - final statusCode = heartbeatResponse.statusCode; - if (statusCode != null && - statusCode != PayloadTypeConstant.heartHeatSuccessResponse) { - // 心跳响应失败,需要重新上线 - _reStartOnlineStartChartServer(); - } - _heartbeatIntervalTime = heartbeatResponse.nextPingTime ?? 1; - } - - /// 处理回声测试 - void _handleUdpEchoTestResultData(ScpMessage scpMessage) { - EasyLoading.showToast(scpMessage.Payload, duration: 2000.milliseconds); - } }