fix:增加对讲数据发送逻辑
This commit is contained in:
parent
aad509e7b9
commit
3200df7793
@ -236,9 +236,9 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
|
||||
}
|
||||
: null)),
|
||||
SubmitBtn(
|
||||
btnName: '跳转至html',
|
||||
btnName: '跳转至通话',
|
||||
onClick: () {
|
||||
Get.toNamed(Routers.LocalHtmlPage);
|
||||
Get.toNamed(Routers.lockMonitoringPage);
|
||||
},
|
||||
),
|
||||
SizedBox(height: 50.w),
|
||||
|
||||
@ -16,6 +16,7 @@ import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/main/lockDetail/monitoring/monitoring/star_chart_logic.dart';
|
||||
import 'package:star_lock/talk/call/callTalk.dart';
|
||||
import 'package:star_lock/talk/startChart/start_chart_talk_status.dart';
|
||||
import 'package:star_lock/talk/startChart/webView/h264_web_view.dart';
|
||||
import 'package:star_lock/talk/udp/udp_manage.dart';
|
||||
import 'package:star_lock/tools/eventBusEventManage.dart';
|
||||
import 'package:star_lock/tools/showTFView.dart';
|
||||
@ -56,62 +57,7 @@ class _LockMonitoringPageState extends State<LockMonitoringPage> {
|
||||
width: 1.sw,
|
||||
height: 1.sh,
|
||||
color: Colors.transparent,
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Image.memory(
|
||||
state.listPhotoData.value,
|
||||
gaplessPlayback: true,
|
||||
width: 1.sw,
|
||||
height: 1.sh,
|
||||
fit: BoxFit.cover,
|
||||
filterQuality: FilterQuality.high,
|
||||
errorBuilder: (BuildContext context, Object error,
|
||||
StackTrace? stackTrace) {
|
||||
return Container(color: Colors.transparent);
|
||||
},
|
||||
),
|
||||
Positioned(
|
||||
top: ScreenUtil().statusBarHeight + 30.h,
|
||||
width: 1.sw,
|
||||
child: Obx(() {
|
||||
final String sec = (state.oneMinuteTime.value % 60)
|
||||
.toString()
|
||||
.padLeft(2, '0');
|
||||
final String min = (state.oneMinuteTime.value ~/ 60)
|
||||
.toString()
|
||||
.padLeft(2, '0');
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text('$min:$sec',
|
||||
style:
|
||||
TextStyle(fontSize: 26.sp, color: Colors.white)),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 10.w,
|
||||
child: Container(
|
||||
width: 1.sw - 30.w * 2,
|
||||
margin: EdgeInsets.all(30.w),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xC83C3F41),
|
||||
borderRadius: BorderRadius.circular(20.h),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20.h),
|
||||
buildTopButtons(),
|
||||
SizedBox(height: 20.h),
|
||||
buildBottomButtons(),
|
||||
SizedBox(height: 20.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: _buildTalkView(isMpeg4: false),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -356,4 +302,109 @@ class _LockMonitoringPageState extends State<LockMonitoringPage> {
|
||||
logic.stopProcessing();
|
||||
state.getTVDataRefreshUIEvent!.cancel();
|
||||
}
|
||||
|
||||
Widget _buildTalkView({required bool isMpeg4}) {
|
||||
return isMpeg4 ? _buildMpeg4TalkView() : _buildH264TalkView();
|
||||
}
|
||||
|
||||
Widget _buildMpeg4TalkView() {
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
Image.memory(
|
||||
state.listPhotoData.value,
|
||||
gaplessPlayback: true,
|
||||
width: 1.sw,
|
||||
height: 1.sh,
|
||||
fit: BoxFit.cover,
|
||||
filterQuality: FilterQuality.high,
|
||||
errorBuilder:
|
||||
(BuildContext context, Object error, StackTrace? stackTrace) {
|
||||
return Container(color: Colors.transparent);
|
||||
},
|
||||
),
|
||||
Positioned(
|
||||
top: ScreenUtil().statusBarHeight + 30.h,
|
||||
width: 1.sw,
|
||||
child: Obx(() {
|
||||
final String sec =
|
||||
(state.oneMinuteTime.value % 60).toString().padLeft(2, '0');
|
||||
final String min =
|
||||
(state.oneMinuteTime.value ~/ 60).toString().padLeft(2, '0');
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text('$min:$sec',
|
||||
style: TextStyle(fontSize: 26.sp, color: Colors.white)),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 10.w,
|
||||
child: Container(
|
||||
width: 1.sw - 30.w * 2,
|
||||
margin: EdgeInsets.all(30.w),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xC83C3F41),
|
||||
borderRadius: BorderRadius.circular(20.h),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20.h),
|
||||
buildTopButtons(),
|
||||
SizedBox(height: 20.h),
|
||||
buildBottomButtons(),
|
||||
SizedBox(height: 20.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildH264TalkView() {
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
H264WebView(),
|
||||
Positioned(
|
||||
top: ScreenUtil().statusBarHeight + 30.h,
|
||||
width: 1.sw,
|
||||
child: Obx(() {
|
||||
final String sec =
|
||||
(state.oneMinuteTime.value % 60).toString().padLeft(2, '0');
|
||||
final String min =
|
||||
(state.oneMinuteTime.value ~/ 60).toString().padLeft(2, '0');
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text('$min:$sec',
|
||||
style: TextStyle(fontSize: 26.sp, color: Colors.white)),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 10.w,
|
||||
child: Container(
|
||||
width: 1.sw - 30.w * 2,
|
||||
margin: EdgeInsets.all(30.w),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xC83C3F41),
|
||||
borderRadius: BorderRadius.circular(20.h),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20.h),
|
||||
buildTopButtons(),
|
||||
SizedBox(height: 20.h),
|
||||
buildBottomButtons(),
|
||||
SizedBox(height: 20.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,6 @@ import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/proto/talk_data.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/proto/talk_data.pbserver.dart';
|
||||
|
||||
|
||||
class UdpTalkDataHandler extends ScpMessageBaseHandle
|
||||
implements ScpMessageHandler {
|
||||
@override
|
||||
@ -24,11 +23,10 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
|
||||
|
||||
@override
|
||||
void handleRealTimeData(ScpMessage scpMessage) {
|
||||
// print('收到音视频数据:$scpMessage');
|
||||
if (scpMessage.Payload != null) {
|
||||
final TalkData talkData = scpMessage.Payload;
|
||||
// 处理音视频数据
|
||||
// _handleTalkData(talkData: talkData);
|
||||
_handleTalkData(talkData: talkData);
|
||||
// 收到数据后调用更新,防止定时器超时
|
||||
talkDataOverTimeTimerManager.receiveMessage();
|
||||
}
|
||||
@ -55,86 +53,10 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
|
||||
|
||||
void _handleVideoH264(TalkData talkData) {
|
||||
final List<int> content = talkData.content;
|
||||
// 解析 H.264 NALU
|
||||
_parseH264Nalus(content);
|
||||
talkDataRepository.addTalkData(content);
|
||||
}
|
||||
|
||||
void _handleVideoImage(TalkData talkData) {}
|
||||
|
||||
void _handleVideoG711(TalkData talkData) {}
|
||||
|
||||
// 解析 H.264 NALU
|
||||
void _parseH264Nalus(List<int> h264Stream) {
|
||||
print('开始解析 H.264 NALU...');
|
||||
|
||||
int index = 0;
|
||||
while (index < h264Stream.length) {
|
||||
// 查找下一个 NALU 的起始码
|
||||
int nextStartCodeIndex = findNextStartCode(h264Stream, index);
|
||||
|
||||
if (nextStartCodeIndex == -1) {
|
||||
// 如果没有找到更多的起始码,结束解析
|
||||
break;
|
||||
}
|
||||
|
||||
// 提取当前 NALU
|
||||
Uint8List naluData =
|
||||
Uint8List.fromList(h264Stream.sublist(index, nextStartCodeIndex));
|
||||
|
||||
// 解析 NALU 头部
|
||||
int naluType = naluData[0] & 0x1F; // NALU 类型位于第一个字节的低 5 位
|
||||
print('找到 NALU,类型: $naluType,长度: ${naluData.length}');
|
||||
|
||||
// 根据 NALU 类型进行处理
|
||||
handleNalu(naluType, naluData);
|
||||
|
||||
// 更新索引到下一个 NALU 的起始位置
|
||||
index = nextStartCodeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// 查找下一个 NALU 的起始码
|
||||
int findNextStartCode(List<int> data, int startIndex) {
|
||||
for (int i = startIndex; i < data.length - 3; i++) {
|
||||
// 检查 3 字节起始码
|
||||
if (data[i] == 0x00 && data[i + 1] == 0x00 && data[i + 2] == 0x01) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// 检查 4 字节起始码
|
||||
if (i < data.length - 4 &&
|
||||
data[i] == 0x00 &&
|
||||
data[i + 1] == 0x00 &&
|
||||
data[i + 2] == 0x00 &&
|
||||
data[i + 3] == 0x01) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有找到更多的起始码,返回 -1
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 处理 NALU
|
||||
void handleNalu(int naluType, Uint8List naluData) {
|
||||
switch (naluType) {
|
||||
case 5:
|
||||
print('IDR 帧 (关键帧)');
|
||||
break;
|
||||
case 1:
|
||||
print('非 IDR 帧 (P 帧)');
|
||||
break;
|
||||
case 7:
|
||||
print('SPS (序列参数集)');
|
||||
break;
|
||||
case 8:
|
||||
print('PPS (图像参数集)');
|
||||
break;
|
||||
default:
|
||||
print('其他 NALU 类型: $naluType');
|
||||
}
|
||||
|
||||
// 你可以在这里根据 NALU 类型进行进一步处理
|
||||
// 例如,将 SPS 和 PPS 传递给解码器,或将视频帧渲染到屏幕上
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||
@ -5,6 +8,7 @@ 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 'package:star_lock/talk/startChart/proto/talk_data.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/proto/talk_expect.pb.dart';
|
||||
|
||||
import '../../start_chart_manage.dart';
|
||||
@ -16,6 +20,12 @@ class UdpTalkExpectHandler extends ScpMessageBaseHandle
|
||||
// 收到预期音视频数据请求
|
||||
final TalkExpect talkExpect = scpMessage.Payload;
|
||||
print('收到预期音视频数据请求:$talkExpect');
|
||||
|
||||
// 回复请求
|
||||
replySuccessMessage(scpMessage);
|
||||
|
||||
// 启动发送通话数据
|
||||
// startChartManage.startTalkDataTimer();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -28,12 +38,8 @@ class UdpTalkExpectHandler extends ScpMessageBaseHandle
|
||||
}
|
||||
|
||||
@override
|
||||
void handleInvalidReq(ScpMessage scpMessage) {
|
||||
|
||||
}
|
||||
void handleInvalidReq(ScpMessage scpMessage) {}
|
||||
|
||||
@override
|
||||
void handleRealTimeData(ScpMessage scpMessage) {
|
||||
|
||||
}
|
||||
void handleRealTimeData(ScpMessage scpMessage) {}
|
||||
}
|
||||
|
||||
30
lib/talk/startChart/handle/other/talk_data_repository.dart
Normal file
30
lib/talk/startChart/handle/other/talk_data_repository.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:star_lock/talk/startChart/proto/talk_data.pb.dart';
|
||||
|
||||
class TalkDataRepository {
|
||||
// 创建一个私有的构造函数,防止外部创建实例
|
||||
TalkDataRepository._();
|
||||
|
||||
// 使用 _instance 来保存单例对象
|
||||
static final TalkDataRepository _instance = TalkDataRepository._();
|
||||
|
||||
// 提供一个静态方法来获取单例实例
|
||||
static TalkDataRepository get instance => _instance;
|
||||
|
||||
// 创建一个 StreamController
|
||||
final StreamController<List<int>> _talkDataStreamController = StreamController<List<int>>.broadcast();
|
||||
|
||||
// 提供一个方法来获取 Stream
|
||||
Stream<List<int>> get talkDataStream => _talkDataStreamController.stream;
|
||||
|
||||
// 提供一个方法来添加 TalkData 到 Stream
|
||||
void addTalkData(List<int> talkData) {
|
||||
_talkDataStreamController.add(talkData);
|
||||
}
|
||||
|
||||
// 提供一个方法来关闭 StreamController
|
||||
void dispose() {
|
||||
_talkDataStreamController.close();
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,9 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/talk/other/audio_player_manager.dart';
|
||||
import 'package:star_lock/talk/startChart/constant/udp_constant.dart';
|
||||
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
||||
import 'package:star_lock/talk/startChart/handle/other/overtime_timer_manger.dart';
|
||||
import 'package:star_lock/talk/startChart/handle/other/talk_data_repository.dart';
|
||||
|
||||
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
|
||||
@ -13,6 +15,9 @@ import 'package:star_lock/talk/startChart/start_chart_talk_status.dart';
|
||||
class ScpMessageBaseHandle {
|
||||
final startChartManage = StartChartManage();
|
||||
|
||||
// 通话数据流的单例流数据处理类
|
||||
final TalkDataRepository talkDataRepository = TalkDataRepository.instance;
|
||||
|
||||
final audioManager = AudioPlayerManager();
|
||||
|
||||
// 通话保持超时监听定时器管理
|
||||
@ -25,12 +30,18 @@ class ScpMessageBaseHandle {
|
||||
timeoutInSeconds: 3,
|
||||
);
|
||||
|
||||
// 回复成功消息
|
||||
void replySuccessMessage(ScpMessage scpMessage){
|
||||
startChartManage.sendGenericRespSuccessMessage(
|
||||
ToPeerId: scpMessage.FromPeerId!,
|
||||
FromPeerId: scpMessage.ToPeerId!,
|
||||
PayloadType: scpMessage.PayloadType!,
|
||||
);
|
||||
}
|
||||
|
||||
// 获取 StartChartTalkStatus 的唯一实例
|
||||
StartChartTalkStatus talkStatus = StartChartTalkStatus.instance;
|
||||
|
||||
|
||||
|
||||
bool checkGenericRespSuccess(GenericResp genericResp) {
|
||||
if (genericResp == null) return false;
|
||||
final code = genericResp.code;
|
||||
|
||||
@ -4,6 +4,7 @@ import 'dart:typed_data';
|
||||
|
||||
import 'package:convert/convert.dart';
|
||||
import 'package:fast_rsa/fast_rsa.dart' as fastRsa;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pointycastle/export.dart' as pc;
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
@ -22,6 +23,7 @@ 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/talk_data.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/proto/talk_expect.pb.dart';
|
||||
import 'package:star_lock/talk/startChart/start_chart_talk_status.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
@ -70,6 +72,8 @@ class StartChartManage {
|
||||
Timer? talkPingTimer; // 发送通话保持消息定时器
|
||||
int talkExpectIntervalTime = 1; // 发送通话预期数据的消息间隔(s)
|
||||
Timer? talkExpectTimer; // 发送通话预期消息定时器
|
||||
int talkDataIntervalTime = 10; // 通话数据的消息间隔(ms)
|
||||
Timer? talkDataTimer; // 发送通话数据消息定时器
|
||||
|
||||
// 默认通话的期望数据格式
|
||||
TalkExpect defaultTalkExpect = TalkExpect(
|
||||
@ -77,6 +81,9 @@ class StartChartManage {
|
||||
audioType: [TalkExpect_AudioTypeE.G711],
|
||||
);
|
||||
|
||||
// 默认通话数据
|
||||
TalkData defaultTalkData = TalkData();
|
||||
|
||||
String relayPeerId = ''; // 中继peerId
|
||||
|
||||
// 获取 StartChartTalkStatus 的唯一实例
|
||||
@ -228,6 +235,17 @@ class StartChartManage {
|
||||
await _sendMessage(message: message);
|
||||
}
|
||||
|
||||
// 发送对讲数据
|
||||
Future<void> sendTalkDataMessage({required TalkData talkData}) async {
|
||||
// 组装上线消息
|
||||
final message = MessageCommand.talkDataMessage(
|
||||
FromPeerId: FromPeerId,
|
||||
ToPeerId: ToPeerId,
|
||||
talkData: talkData,
|
||||
);
|
||||
await _sendMessage(message: message);
|
||||
}
|
||||
|
||||
// 发送心跳包消息
|
||||
void _sendHeartbeatMessage() async {
|
||||
if (_heartBeatTimerRunning) {
|
||||
@ -764,6 +782,108 @@ class StartChartManage {
|
||||
);
|
||||
}
|
||||
|
||||
/// 通话数据定时器
|
||||
void startTalkDataTimer() async {
|
||||
// 如果已经启动了就不运行
|
||||
if (talkDataTimer != null) return;
|
||||
// 读取 assets 文件
|
||||
final ByteData data = await rootBundle.load('assets/talk.h264');
|
||||
final List<int> byteData = data.buffer.asUint8List();
|
||||
int current = 0;
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
final List<int> chunks = extractChunks(byteData);
|
||||
talkDataTimer ??= Timer.periodic(
|
||||
Duration(
|
||||
milliseconds: talkDataIntervalTime,
|
||||
),
|
||||
(Timer timer) {
|
||||
if (current >= chunks.length) {
|
||||
print('数据已经发完');
|
||||
start = 0;
|
||||
end = 0;
|
||||
current = 0;
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// 提取 NALU 边界并生成 chunks
|
||||
end = chunks[current];
|
||||
current++;
|
||||
List<int> frameData = byteData.sublist(start, end);
|
||||
if (frameData.length == 0) timer.cancel();
|
||||
defaultTalkData = TalkData(
|
||||
content: frameData,
|
||||
contentType: TalkData_ContentTypeE.H264,
|
||||
);
|
||||
start = end;
|
||||
// 发送童话数据
|
||||
sendTalkDataMessage(talkData: defaultTalkData);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
List<int> extractChunks(List<int> byteData) {
|
||||
int i = 0;
|
||||
int length = byteData.length;
|
||||
int naluCount = 0;
|
||||
int value;
|
||||
int state = 0;
|
||||
int lastIndex = 0;
|
||||
List<int> result = [];
|
||||
const minNaluPerChunk = 22; // 每个数据块包含的最小NALU数量
|
||||
|
||||
while (i < length) {
|
||||
value = byteData[i++];
|
||||
// finding 3 or 4-byte start codes (00 00 01 OR 00 00 00 01)
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (value == 0) {
|
||||
state = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (value == 0) {
|
||||
state = 2;
|
||||
} else {
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
if (value == 0) {
|
||||
state = 3;
|
||||
} else if (value == 1 && i < length) {
|
||||
if (lastIndex > 0) {
|
||||
naluCount++;
|
||||
}
|
||||
if (naluCount >= minNaluPerChunk) {
|
||||
result.add(lastIndex - state - 1);
|
||||
naluCount = 0;
|
||||
}
|
||||
state = 0;
|
||||
lastIndex = i;
|
||||
} else {
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (naluCount > 0) {
|
||||
result.add(lastIndex);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 停止发送通话数据
|
||||
void stopTalkDataTimer() {
|
||||
talkDataTimer?.cancel();
|
||||
talkDataTimer = null; // 清除定时器引用
|
||||
}
|
||||
|
||||
// 停止发送通话期望数据
|
||||
void stopTalkExpectMessageTimer() {
|
||||
talkExpectTimer?.cancel();
|
||||
@ -781,6 +901,7 @@ class StartChartManage {
|
||||
stopTalkPingMessageTimer();
|
||||
stopHeartbeat();
|
||||
stopReStartOnlineStartChartServer();
|
||||
stopTalkDataTimer();
|
||||
await Storage.removerRelayInfo();
|
||||
await Storage.removerStarChartRegisterNodeInfo();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user