Socket null handling (#1610)
* return null if in connection failure state * reconnect on connection failure * better connection handling * probably not necessary but just incase * connection handling updates * add cancelOnError: true
Matthew Fosse committed
Aug 17, 2024 at 19:28 UTC
7c9b72483a66e113db6fee8c23d3b8616c76c41f
2 files changed
+40
-36
cw_bitcoin/lib/electrum.dart
+31
-23
@@ -66,6 +66,7 @@ class ElectrumClient {
66
67
try {
68
await socket?.close();
69
+ socket = null;
70
} catch (_) {}
71
72
try {
@@ -90,33 +91,40 @@ class ElectrumClient {
91
}
92
_setConnectionStatus(ConnectionStatus.connected);
93
93
- socket!.listen((Uint8List event) {
94
- try {
95
- final msg = utf8.decode(event.toList());
96
- final messagesList = msg.split("\n");
97
- for (var message in messagesList) {
98
- if (message.isEmpty) {
99
- continue;
94
+ socket!.listen(
95
+ (Uint8List event) {
96
+ try {
97
+ final msg = utf8.decode(event.toList());
98
+ final messagesList = msg.split("\n");
99
+ for (var message in messagesList) {
100
+ if (message.isEmpty) {
101
+ continue;
102
+ }
103
+ _parseResponse(message);
104
}
101
- _parseResponse(message);
105
+ } catch (e) {
106
+ print(e.toString());
107
}
103
- } catch (e) {
104
- print(e.toString());
105
- }
106
- }, onError: (Object error) {
107
- final errorMsg = error.toString();
108
- print(errorMsg);
109
- unterminatedString = '';
108
+ },
109
+ onError: (Object error) {
110
+ socket = null;
111
+ final errorMsg = error.toString();
112
+ print(errorMsg);
113
+ unterminatedString = '';
114
111
- final currentHost = socket?.address.host;
112
- final isErrorForCurrentHost = errorMsg.contains(" ${currentHost} ");
115
+ final currentHost = socket?.address.host;
116
+ final isErrorForCurrentHost = errorMsg.contains(" ${currentHost} ");
117
114
- if (currentHost != null && isErrorForCurrentHost)
115
- _setConnectionStatus(ConnectionStatus.failed);
116
- }, onDone: () {
117
- unterminatedString = '';
118
- if (host == socket?.address.host) _setConnectionStatus(ConnectionStatus.disconnected);
119
- });
118
+ if (currentHost != null && isErrorForCurrentHost)
119
+ _setConnectionStatus(ConnectionStatus.failed);
120
+ },
121
+ onDone: () {
122
+ socket = null;
123
+ unterminatedString = '';
124
+ if (host == socket?.address.host) _setConnectionStatus(ConnectionStatus.disconnected);
125
+ },
126
+ cancelOnError: true,
127
+ );
128
129
keepAlive();
130
}
cw_bitcoin/lib/electrum_wallet.dart
+9
-13
@@ -218,10 +218,7 @@ abstract class ElectrumWalletBase
218
if (electrumClient.isConnected) {
219
syncStatus = SyncedSyncStatus();
220
} else {
221
- if (electrumClient.uri != null) {
222
- await electrumClient.connectToUri(electrumClient.uri!, useSSL: electrumClient.useSSL);
223
- startSync();
224
- }
221
+ syncStatus = NotConnectedSyncStatus();
222
}
223
}
224
}
@@ -265,6 +262,7 @@ abstract class ElectrumWalletBase
262
Future<Isolate>? _isolate;
263
264
void Function(FlutterErrorDetails)? _onError;
265
+ Timer? _reconnectTimer;
266
Timer? _autoSaveTimer;
267
static const int _autoSaveInterval = 30;
268
@@ -1980,13 +1978,6 @@ abstract class ElectrumWalletBase
1978
break;
1979
case ConnectionStatus.failed:
1980
syncStatus = LostConnectionSyncStatus();
1983
- // wait for 5 seconds and then try to reconnect:
1984
- Future.delayed(Duration(seconds: 5), () {
1985
- electrumClient.connectToUri(
1986
- node!.uri,
1987
- useSSL: node!.useSSL ?? false,
1988
- );
1989
- });
1981
break;
1982
case ConnectionStatus.connecting:
1983
syncStatus = ConnectingSyncStatus();
@@ -1996,7 +1987,11 @@ abstract class ElectrumWalletBase
1987
}
1988
1989
void _syncStatusReaction(SyncStatus syncStatus) async {
1999
- if (syncStatus is NotConnectedSyncStatus) {
1990
+ if (syncStatus is SyncingSyncStatus) {
1991
+ return;
1992
+ }
1993
+
1994
+ if (syncStatus is NotConnectedSyncStatus || syncStatus is LostConnectionSyncStatus) {
1995
// Needs to re-subscribe to all scripthashes when reconnected
1996
_scripthashesUpdateSubject = {};
1997
@@ -2004,7 +1999,8 @@ abstract class ElectrumWalletBase
1999
2000
_isTryingToConnect = true;
2001
2007
- Future.delayed(Duration(seconds: 10), () {
2002
+ _reconnectTimer?.cancel();
2003
+ _reconnectTimer = Timer(Duration(seconds: 10), () {
2004
if (this.syncStatus is! SyncedSyncStatus && this.syncStatus is! SyncedTipSyncStatus) {
2005
this.electrumClient.connectToUri(
2006
node!.uri,