mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-12 20:02:01 +10:00
fix(tcp): guard connect cancellation race and align USB screen actions
- add connectTcp cancellation guards after socket connect and connect delay so handshake does not proceed when transport/state changed - ignore late TCP connect errors after manual cancel or transport switch to avoid spurious second disconnect paths - keep TCP action hidden only on web and show Bluetooth action on USB screen across platforms for navigation consistency
This commit is contained in:
@@ -995,9 +995,37 @@ class MeshCoreConnector extends ChangeNotifier {
|
|||||||
await _tcpFrameSubscription?.cancel();
|
await _tcpFrameSubscription?.cancel();
|
||||||
_tcpFrameSubscription = null;
|
_tcpFrameSubscription = null;
|
||||||
await _tcpManager.connect(host: host, port: port);
|
await _tcpManager.connect(host: host, port: port);
|
||||||
|
final isTcpConnectCancelled =
|
||||||
|
_activeTransport != MeshCoreTransportType.tcp ||
|
||||||
|
_state != MeshCoreConnectionState.connecting ||
|
||||||
|
!_tcpManager.isConnected;
|
||||||
|
if (isTcpConnectCancelled) {
|
||||||
|
_appDebugLogService?.warn(
|
||||||
|
'connectTcp aborted before handshake: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}',
|
||||||
|
tag: 'TCP',
|
||||||
|
);
|
||||||
|
if (_tcpManager.isConnected) {
|
||||||
|
await _tcpManager.disconnect();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
await Future<void>.delayed(const Duration(milliseconds: 200));
|
await Future<void>.delayed(const Duration(milliseconds: 200));
|
||||||
|
final isTcpConnectCancelledAfterDelay =
|
||||||
|
_activeTransport != MeshCoreTransportType.tcp ||
|
||||||
|
_state != MeshCoreConnectionState.connecting ||
|
||||||
|
!_tcpManager.isConnected;
|
||||||
|
if (isTcpConnectCancelledAfterDelay) {
|
||||||
|
_appDebugLogService?.warn(
|
||||||
|
'connectTcp aborted after connect delay: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}',
|
||||||
|
tag: 'TCP',
|
||||||
|
);
|
||||||
|
if (_tcpManager.isConnected) {
|
||||||
|
await _tcpManager.disconnect();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
_tcpFrameSubscription = _tcpManager.frameStream.listen(
|
_tcpFrameSubscription = _tcpManager.frameStream.listen(
|
||||||
_handleFrame,
|
_handleFrame,
|
||||||
onError: (error, stackTrace) {
|
onError: (error, stackTrace) {
|
||||||
@@ -1031,6 +1059,16 @@ class MeshCoreConnector extends ChangeNotifier {
|
|||||||
await syncTime();
|
await syncTime();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
_appDebugLogService?.error('TCP connection error: $error', tag: 'TCP');
|
_appDebugLogService?.error('TCP connection error: $error', tag: 'TCP');
|
||||||
|
final tcpConnectNoLongerActive =
|
||||||
|
_activeTransport != MeshCoreTransportType.tcp ||
|
||||||
|
_state != MeshCoreConnectionState.connecting;
|
||||||
|
if (tcpConnectNoLongerActive) {
|
||||||
|
_appDebugLogService?.info(
|
||||||
|
'Ignoring late TCP connect error after cancellation/switch: state=$_state transport=$_activeTransport',
|
||||||
|
tag: 'TCP',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
await disconnect(manual: false);
|
await disconnect(manual: false);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,10 +108,7 @@ class _UsbScreenState extends State<UsbScreen> {
|
|||||||
bottomNavigationBar: Consumer<MeshCoreConnector>(
|
bottomNavigationBar: Consumer<MeshCoreConnector>(
|
||||||
builder: (context, connector, child) {
|
builder: (context, connector, child) {
|
||||||
final isLoading = _isLoadingPorts;
|
final isLoading = _isLoadingPorts;
|
||||||
final showBle =
|
final showBle = true;
|
||||||
PlatformInfo.isWeb ||
|
|
||||||
PlatformInfo.isAndroid ||
|
|
||||||
PlatformInfo.isIOS;
|
|
||||||
final showTcp = !PlatformInfo.isWeb;
|
final showTcp = !PlatformInfo.isWeb;
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
|
|||||||
Reference in New Issue
Block a user