fix:调整udp返回数据为工厂模式处理
This commit is contained in:
parent
5054f2a68a
commit
857f9fad2a
@ -36,6 +36,7 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
|
|||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
AppFirstEnterHandle().getAppFirstEnter(isAgreePrivacy);
|
AppFirstEnterHandle().getAppFirstEnter(isAgreePrivacy);
|
||||||
});
|
});
|
||||||
|
StartChartManage().init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -233,12 +234,6 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
: null)),
|
: null)),
|
||||||
SubmitBtn(
|
|
||||||
btnName: '初始化星图服务',
|
|
||||||
onClick: () async {
|
|
||||||
await StartChartManage().init();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SubmitBtn(
|
SubmitBtn(
|
||||||
btnName: '发送回声测试消息',
|
btnName: '发送回声测试消息',
|
||||||
onClick: () {
|
onClick: () {
|
||||||
@ -251,7 +246,7 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
|
|||||||
onClick: () {
|
onClick: () {
|
||||||
StartChartManage().sendGatewayResetMessage(
|
StartChartManage().sendGatewayResetMessage(
|
||||||
ToPeerId: '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH',
|
ToPeerId: '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH',
|
||||||
gatewayId: 1,
|
gatewayId: 1000000000,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@ -79,11 +79,13 @@ class MessageCommand {
|
|||||||
required String ToPeerId,
|
required String ToPeerId,
|
||||||
required int time,
|
required int time,
|
||||||
}) {
|
}) {
|
||||||
|
// 构建荷载
|
||||||
final gatewayResetReq = GatewayResetReq(
|
final gatewayResetReq = GatewayResetReq(
|
||||||
iD: gatewayId,
|
iD: gatewayId,
|
||||||
time: time,
|
time: time,
|
||||||
);
|
);
|
||||||
final payloadLength = gatewayResetReq.writeToBuffer().length;
|
// 构建荷载参数
|
||||||
|
final payload = gatewayResetReq.writeToBuffer();
|
||||||
ScpMessage message = ScpMessage(
|
ScpMessage message = ScpMessage(
|
||||||
ProtocolFlag: ProtocolFlagConstant.scp01,
|
ProtocolFlag: ProtocolFlagConstant.scp01,
|
||||||
MessageType: MessageTypeConstant.Req,
|
MessageType: MessageTypeConstant.Req,
|
||||||
@ -92,9 +94,9 @@ class MessageCommand {
|
|||||||
SpIndex: 0,
|
SpIndex: 0,
|
||||||
FromPeerId: FromPeerId,
|
FromPeerId: FromPeerId,
|
||||||
ToPeerId: ToPeerId,
|
ToPeerId: ToPeerId,
|
||||||
Payload: gatewayResetReq,
|
Payload: payload,
|
||||||
PayloadCRC: 55230,
|
PayloadCRC: 55230,
|
||||||
PayloadLength: payloadLength,
|
PayloadLength: payload.length,
|
||||||
PayloadType: PayloadTypeConstant.gatewayReset,
|
PayloadType: PayloadTypeConstant.gatewayReset,
|
||||||
);
|
);
|
||||||
String serializedBytesString = message.serialize();
|
String serializedBytesString = message.serialize();
|
||||||
|
|||||||
5
lib/talk/startChart/constant/udp_constant.dart
Normal file
5
lib/talk/startChart/constant/udp_constant.dart
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class UdpConstant{
|
||||||
|
// generic成功响应
|
||||||
|
static const int genericRespSuccessCode = 0;
|
||||||
|
static const String genericRespSuccessMsg = 'ok';
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:crc32_checksum/crc32_checksum.dart';
|
import 'package:crc32_checksum/crc32_checksum.dart';
|
||||||
import 'package:crypto/crypto.dart';
|
import 'package:crypto/crypto.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/app_settings/app_settings.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/constant/payload_type_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/heartbeat_response.dart';
|
import 'package:star_lock/talk/startChart/entity/heartbeat_response.dart';
|
||||||
@ -140,6 +141,9 @@ class ScpMessage {
|
|||||||
// Payload (字符串,转换为字节)
|
// Payload (字符串,转换为字节)
|
||||||
if (Payload != null && Payload is String) {
|
if (Payload != null && Payload is String) {
|
||||||
bytes.addAll(utf8.encode(Payload!));
|
bytes.addAll(utf8.encode(Payload!));
|
||||||
|
} else {
|
||||||
|
// 如果不是字符串则需要外部转为字节数组,这里直接添加
|
||||||
|
bytes.addAll(Payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转16进制字符串
|
// 转16进制字符串
|
||||||
@ -277,65 +281,76 @@ class ScpMessage {
|
|||||||
int? offset,
|
int? offset,
|
||||||
int? PayloadLength,
|
int? PayloadLength,
|
||||||
}) {
|
}) {
|
||||||
switch (payloadType) {
|
try {
|
||||||
case PayloadTypeConstant.goOnline:
|
switch (payloadType) {
|
||||||
// 上线
|
case PayloadTypeConstant.goOnline:
|
||||||
LoginResponse loginResp = LoginResponse.fromBytes(byte);
|
// 上线
|
||||||
return loginResp;
|
LoginResponse loginResp = LoginResponse.fromBytes(byte);
|
||||||
case PayloadTypeConstant.heartbeat:
|
return loginResp;
|
||||||
// 心跳
|
case PayloadTypeConstant.heartbeat:
|
||||||
HeartbeatResponse heartbeatResponse = HeartbeatResponse.fromBytes(byte);
|
// 心跳
|
||||||
return heartbeatResponse;
|
HeartbeatResponse heartbeatResponse =
|
||||||
case PayloadTypeConstant.echoTest:
|
HeartbeatResponse.fromBytes(byte);
|
||||||
// 回声测试
|
return heartbeatResponse;
|
||||||
String payload = utf8.decode(byte);
|
case PayloadTypeConstant.echoTest:
|
||||||
return payload;
|
// 回声测试
|
||||||
case PayloadTypeConstant.gatewayReset:
|
String payload = utf8.decode(byte);
|
||||||
// 初始化网关
|
return payload;
|
||||||
final GatewayResetResp gatewayResetResp =
|
case PayloadTypeConstant.gatewayReset:
|
||||||
GatewayResetResp.fromBuffer(byte);
|
// 初始化网关
|
||||||
return gatewayResetResp;
|
final GatewayResetResp gatewayResetResp =
|
||||||
case PayloadTypeConstant.callRequest:
|
GatewayResetResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return gatewayResetResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.callRequest:
|
||||||
case PayloadTypeConstant.talkAccept:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return genericResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.talkAccept:
|
||||||
case PayloadTypeConstant.gatewayTransfer:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return genericResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.gatewayTransfer:
|
||||||
case PayloadTypeConstant.blePassthrough:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
final BleResp bleResp = BleResp.fromBuffer(byte);
|
return genericResp;
|
||||||
return bleResp;
|
case PayloadTypeConstant.blePassthrough:
|
||||||
case PayloadTypeConstant.remoteUnlock:
|
final BleResp bleResp = BleResp.fromBuffer(byte);
|
||||||
final RemoteUnlockResp remoteUnlockResp =
|
return bleResp;
|
||||||
RemoteUnlockResp.fromBuffer(byte);
|
case PayloadTypeConstant.remoteUnlock:
|
||||||
return remoteUnlockResp;
|
final RemoteUnlockResp remoteUnlockResp =
|
||||||
case PayloadTypeConstant.talkReceiverTransfer:
|
RemoteUnlockResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return remoteUnlockResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.talkReceiverTransfer:
|
||||||
case PayloadTypeConstant.talkPush:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return genericResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.talkPush:
|
||||||
case PayloadTypeConstant.talkReject:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return genericResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.talkReject:
|
||||||
case PayloadTypeConstant.talkPing:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return genericResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.talkPing:
|
||||||
case PayloadTypeConstant.talkExpect:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return genericResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.talkExpect:
|
||||||
case PayloadTypeConstant.talkData:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return genericResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.talkData:
|
||||||
case PayloadTypeConstant.talkHangup:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
return genericResp;
|
||||||
return genericResp;
|
case PayloadTypeConstant.talkHangup:
|
||||||
default:
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
print('❌未知的payloadType类型,按照字符串解析');
|
return genericResp;
|
||||||
String payload = utf8.decode(byte);
|
default:
|
||||||
return payload;
|
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}');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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: <String, String>{'lockId': '111'},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
lib/talk/startChart/handle/impl/udp_echo_test_handler.dart
Normal file
14
lib/talk/startChart/handle/impl/udp_echo_test_handler.dart
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 网关初始化成功
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
lib/talk/startChart/handle/impl/udp_go_online_handler.dart
Normal file
27
lib/talk/startChart/handle/impl/udp_go_online_handler.dart
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
lib/talk/startChart/handle/impl/udp_heart_beat_handler.dart
Normal file
26
lib/talk/startChart/handle/impl/udp_heart_beat_handler.dart
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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类型');
|
||||||
|
}
|
||||||
|
}
|
||||||
17
lib/talk/startChart/handle/scp_message_base_handle.dart
Normal file
17
lib/talk/startChart/handle/scp_message_base_handle.dart
Normal file
@ -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}');
|
||||||
|
}
|
||||||
|
}
|
||||||
5
lib/talk/startChart/handle/scp_message_handle.dart
Normal file
5
lib/talk/startChart/handle/scp_message_handle.dart
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||||
|
|
||||||
|
abstract class ScpMessageHandler {
|
||||||
|
void handle(ScpMessage scpMessage);
|
||||||
|
}
|
||||||
27
lib/talk/startChart/handle/scp_message_handler_factory.dart
Normal file
27
lib/talk/startChart/handle/scp_message_handler_factory.dart
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ import 'package:fast_rsa/fast_rsa.dart' as fastRsa;
|
|||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:pointycastle/export.dart' as pc;
|
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/app_settings/app_settings.dart';
|
||||||
import 'package:star_lock/flavors.dart';
|
import 'package:star_lock/flavors.dart';
|
||||||
import 'package:star_lock/network/start_chart_api.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/ip_constant.dart';
|
||||||
import 'package:star_lock/talk/startChart/constant/listen_addr_type_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/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/heartbeat_response.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/login_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/relay_info_entity.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/report_information_data.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/scp_message.dart';
|
||||||
import 'package:star_lock/talk/startChart/entity/star_chart_register_node_entity.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/deviceInfo_utils.dart';
|
||||||
import 'package:star_lock/tools/storage.dart';
|
import 'package:star_lock/tools/storage.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
@ -48,7 +54,7 @@ class StartChartManage {
|
|||||||
final int localPort = 62289; // 本地端口
|
final int localPort = 62289; // 本地端口
|
||||||
String localPublicHost = ''; // 本地公网ip地址
|
String localPublicHost = ''; // 本地公网ip地址
|
||||||
|
|
||||||
int _heartbeatIntervalTime = 1; // 心跳包间隔时间(s)
|
int heartbeatIntervalTime = 1; // 心跳包间隔时间(s)
|
||||||
Timer? _heartBeatTimer; // 心跳包定时器
|
Timer? _heartBeatTimer; // 心跳包定时器
|
||||||
bool _heartBeatTimerRunning = false; // 心跳包定时任务发送状态
|
bool _heartBeatTimerRunning = false; // 心跳包定时任务发送状态
|
||||||
|
|
||||||
@ -58,16 +64,15 @@ class StartChartManage {
|
|||||||
// echo测试peer对端
|
// echo测试peer对端
|
||||||
final String echoPeerId = '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH';
|
final String echoPeerId = '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH';
|
||||||
|
|
||||||
bool _isOnlineStartChartServer = false; // 星图是否上线成功
|
bool isOnlineStartChartServer = false; // 星图是否上线成功
|
||||||
int _reStartOnlineStartChartServerIntervalTime = 1; // 重新上线星图服务任务间隔(s)
|
int reStartOnlineStartChartServerIntervalTime = 1; // 重新上线星图服务任务间隔(s)
|
||||||
Timer? _reStartOnlineStartChartServerTimer; // 重新上线定时器
|
Timer? reStartOnlineStartChartServerTimer; // 重新上线定时器
|
||||||
bool _reStartOnlineStartChartServerTimerRunning = false; // 重新上线定时任务发送状态
|
|
||||||
|
|
||||||
String relayPeerId = ''; // 中继peerId
|
String relayPeerId = ''; // 中继peerId
|
||||||
|
|
||||||
// 星图服务初始化
|
// 星图服务初始化
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
if (_isOnlineStartChartServer && _udpSocket != null) {
|
if (isOnlineStartChartServer && _udpSocket != null) {
|
||||||
// 如果已经上线就不进行初始化
|
// 如果已经上线就不进行初始化
|
||||||
return;
|
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<void> reportInformation() async {
|
Future<void> reportInformation() async {
|
||||||
_log(text: '上报信息至发现服务');
|
_log(text: '上报信息至发现服务');
|
||||||
@ -168,13 +151,13 @@ class StartChartManage {
|
|||||||
// 发送心跳消息
|
// 发送心跳消息
|
||||||
_sendHeartbeatMessage();
|
_sendHeartbeatMessage();
|
||||||
// 发送送上线消息
|
// 发送送上线消息
|
||||||
await _reStartOnlineStartChartServer();
|
await reStartOnlineStartChartServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送上线消息
|
// 发送上线消息
|
||||||
Future<void> _sendOnlineMessage() async {
|
Future<void> _sendOnlineMessage() async {
|
||||||
if (_isOnlineStartChartServer) {
|
if (isOnlineStartChartServer) {
|
||||||
_log(text: '星图已上线,请勿重复发送上线消息');
|
_log(text: '星图已上线,请勿重复发送上线消息');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -194,7 +177,7 @@ class StartChartManage {
|
|||||||
}
|
}
|
||||||
_heartBeatTimer ??= Timer.periodic(
|
_heartBeatTimer ??= Timer.periodic(
|
||||||
Duration(
|
Duration(
|
||||||
seconds: _heartbeatIntervalTime,
|
seconds: heartbeatIntervalTime,
|
||||||
),
|
),
|
||||||
(Timer timer) async {
|
(Timer timer) async {
|
||||||
final List<int> message = MessageCommand.heartbeatMessage(
|
final List<int> message = MessageCommand.heartbeatMessage(
|
||||||
@ -223,27 +206,36 @@ class StartChartManage {
|
|||||||
ToPeerId: ToPeerId,
|
ToPeerId: ToPeerId,
|
||||||
FromPeerId: FromPeerId,
|
FromPeerId: FromPeerId,
|
||||||
gatewayId: gatewayId,
|
gatewayId: gatewayId,
|
||||||
time: DateTime.now().microsecond ~/ 1000,
|
time: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||||
);
|
);
|
||||||
await _sendMessage(message: message);
|
await _sendMessage(message: message);
|
||||||
|
Get.toNamed(
|
||||||
|
Routers.lockMonitoringPage,
|
||||||
|
arguments: <String, String>{'lockId': '111'},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重新上线
|
// 重新上线
|
||||||
Future<void> _reStartOnlineStartChartServer() async {
|
Future<void> reStartOnlineStartChartServer() async {
|
||||||
if (_isOnlineStartChartServer) {
|
if (isOnlineStartChartServer) {
|
||||||
_log(text: '星图已上线,请勿重复发送上线消息');
|
_log(text: '星图已上线,请勿重复发送上线消息');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_reStartOnlineStartChartServerTimer ??= Timer.periodic(
|
reStartOnlineStartChartServerTimer ??= Timer.periodic(
|
||||||
Duration(
|
Duration(
|
||||||
seconds: _reStartOnlineStartChartServerIntervalTime,
|
seconds: reStartOnlineStartChartServerIntervalTime,
|
||||||
),
|
),
|
||||||
(Timer timer) async {
|
(Timer timer) async {
|
||||||
// 重新发送上线消息
|
// 重新发送上线消息
|
||||||
await _sendOnlineMessage();
|
await _sendOnlineMessage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
_reStartOnlineStartChartServerTimerRunning = true;
|
}
|
||||||
|
|
||||||
|
// 重新发送心跳
|
||||||
|
void reStartHeartBeat() {
|
||||||
|
stopHeartbeat();
|
||||||
|
_sendHeartbeatMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 停止定时发送心跳包
|
// 停止定时发送心跳包
|
||||||
@ -255,9 +247,8 @@ class StartChartManage {
|
|||||||
|
|
||||||
// 停止重新上线
|
// 停止重新上线
|
||||||
void stopReStartOnlineStartChartServer() {
|
void stopReStartOnlineStartChartServer() {
|
||||||
_reStartOnlineStartChartServerTimer?.cancel();
|
reStartOnlineStartChartServerTimer?.cancel();
|
||||||
_reStartOnlineStartChartServerTimer = null; // 清除定时器引用
|
reStartOnlineStartChartServerTimer = null; // 清除定时器引用
|
||||||
_reStartOnlineStartChartServerTimerRunning = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
@ -341,6 +332,11 @@ class StartChartManage {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解析对端数据
|
||||||
|
Future<void> analyzeInformationOtherEnd() async {
|
||||||
|
await StartChartApi.to.analyzeInformationOtherEnd(peerId: ToPeerId);
|
||||||
|
}
|
||||||
|
|
||||||
// 获取本机所有ip地址和中继返回的外网地址
|
// 获取本机所有ip地址和中继返回的外网地址
|
||||||
Future<List<ListenAddrData>> _makeListenAddrDataList() async {
|
Future<List<ListenAddrData>> _makeListenAddrDataList() async {
|
||||||
final List<ListenAddrData> listenAddrDataList = [];
|
final List<ListenAddrData> listenAddrDataList = [];
|
||||||
@ -459,7 +455,7 @@ class StartChartManage {
|
|||||||
return resultSign ?? '';
|
return resultSign ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将 32 位时间戳以小端字节序编码为二进制数据
|
// 将 32 位时间戳以小端字节序编码为二进制数据
|
||||||
Uint8List encodeTimestampToLittleEndianBytes(int timestamp) {
|
Uint8List encodeTimestampToLittleEndianBytes(int timestamp) {
|
||||||
// 创建一个 4 字节的 ByteData 对象
|
// 创建一个 4 字节的 ByteData 对象
|
||||||
ByteData byteData = ByteData(4);
|
ByteData byteData = ByteData(4);
|
||||||
@ -473,6 +469,7 @@ class StartChartManage {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 转换私钥格式
|
||||||
String convertToPemPrivateKey(List<int> privateKeyBytes,
|
String convertToPemPrivateKey(List<int> privateKeyBytes,
|
||||||
{bool isPKCS8 = true}) {
|
{bool isPKCS8 = true}) {
|
||||||
// 将字节数组转换为Base64编码的字符串
|
// 将字节数组转换为Base64编码的字符串
|
||||||
@ -531,11 +528,6 @@ class StartChartManage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析对端数据
|
|
||||||
Future<void> analyzeInformationOtherEnd() async {
|
|
||||||
await StartChartApi.to.analyzeInformationOtherEnd(peerId: ToPeerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将十六进制字符串转换为字节数组
|
// 将十六进制字符串转换为字节数组
|
||||||
List<int> hexToBytes(String hex) {
|
List<int> hexToBytes(String hex) {
|
||||||
return List<int>.generate(hex.length ~/ 2,
|
return List<int>.generate(hex.length ~/ 2,
|
||||||
@ -549,6 +541,7 @@ class StartChartManage {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 获取公钥
|
||||||
Future<String> getPublicKey() async {
|
Future<String> getPublicKey() async {
|
||||||
// 从缓存中获取星图注册节点信息
|
// 从缓存中获取星图注册节点信息
|
||||||
final StarChartRegisterNodeEntity? starChartRegisterNodeInfo =
|
final StarChartRegisterNodeEntity? starChartRegisterNodeInfo =
|
||||||
@ -556,6 +549,7 @@ class StartChartManage {
|
|||||||
return starChartRegisterNodeInfo?.peer?.publicKey ?? '';
|
return starChartRegisterNodeInfo?.peer?.publicKey ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 获取私钥
|
||||||
Future<String> getPrivateKey() async {
|
Future<String> getPrivateKey() async {
|
||||||
// 从缓存中获取星图注册节点信息
|
// 从缓存中获取星图注册节点信息
|
||||||
final StarChartRegisterNodeEntity? starChartRegisterNodeInfo =
|
final StarChartRegisterNodeEntity? starChartRegisterNodeInfo =
|
||||||
@ -563,119 +557,37 @@ class StartChartManage {
|
|||||||
return starChartRegisterNodeInfo?.peer?.privateKey ?? '';
|
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返回的数据
|
// 处理udp返回的数据
|
||||||
void _handleUdpResultData(ScpMessage scpMessage) {
|
void _handleUdpResultData(ScpMessage scpMessage) {
|
||||||
final int payloadType = scpMessage.PayloadType ?? 0;
|
final int payloadType = scpMessage.PayloadType ?? 0;
|
||||||
switch (payloadType) {
|
try {
|
||||||
case PayloadTypeConstant.goOnline:
|
final ScpMessageHandler handler =
|
||||||
_handleUdpGoOnlineResultData(scpMessage);
|
ScpMessageHandlerFactory.createHandler(payloadType);
|
||||||
break;
|
handler.handle(scpMessage);
|
||||||
case PayloadTypeConstant.heartbeat:
|
} catch (e) {
|
||||||
_handleUdpHeartBeatResultData(scpMessage);
|
_log(text: '❌ _handleUdpResultData 处理udp返回数据时遇到错误---> $e');
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 处理上线命令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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user