fix: report isClosed from ProxySocket and use it to reconnect (#2617)

cyan committed Oct 30, 2025 at 02:16 UTC 00b99a9fa0e292b042914ac509c29ce8ba29d274
5 files changed +21 -23
cw_bitcoin/lib/electrum.dart
+4 -7
@@ -35,7 +35,6 @@ class SocketTask {
35 class ElectrumClient {
36 ElectrumClient()
37 : _id = 0,
38 - _isConnected = false,
38 _tasks = {},
39 _errors = {},
40 unterminatedString = '';
@@ -43,7 +42,7 @@ class ElectrumClient {
42 static const connectionTimeout = Duration(seconds: 5);
43 static const aliveTimerDuration = Duration(seconds: 4);
44
46 - bool get isConnected => _isConnected && socket != null;
45 + bool get isConnected => socket != null && socket?.isClosed == false;
46 ProxySocket? socket;
47 void Function(ConnectionStatus)? onConnectionStatusChange;
48 int _id;
@@ -51,7 +50,6 @@ class ElectrumClient {
50 Map<String, SocketTask> get tasks => _tasks;
51 final Map<String, String> _errors;
52 ConnectionStatus _connectionStatus = ConnectionStatus.disconnected;
54 - bool _isConnected;
53 Timer? _aliveTimer;
54 String unterminatedString;
55
@@ -451,7 +449,7 @@ class ElectrumClient {
449
450 Future<dynamic> call(
451 {required String method, List<Object> params = const [], Function(int)? idCallback}) async {
454 - if (!_isConnected || socket == null) return null;
452 + if (!isConnected) return null;
453
454 final completer = Completer<dynamic>();
455 _id += 1;
@@ -466,7 +464,7 @@ class ElectrumClient {
464 Future<dynamic> callWithTimeout(
465 {required String method, List<Object> params = const [], int timeout = 5000}) async {
466 try {
469 - if (!_isConnected || socket == null) return null;
467 + if (!isConnected) return null;
468
469 final completer = Completer<dynamic>();
470 _id += 1;
@@ -564,8 +562,7 @@ class ElectrumClient {
562 void _setConnectionStatus(ConnectionStatus status) {
563 onConnectionStatusChange?.call(status);
564 _connectionStatus = status;
567 - _isConnected = status == ConnectionStatus.connected;
568 - if (!_isConnected) {
565 + if (!isConnected) {
566 try {
567 socket?.destroy();
568 } catch (_) {}
cw_core/lib/utils/proxy_socket/abstract.dart
+1
@@ -42,6 +42,7 @@ abstract class ProxySocket {
42 Future<void> close();
43 void destroy();
44 void write(String data);
45 + bool get isClosed;
46 StreamSubscription<List<int>> listen(Function(Uint8List event) onData, {Function (Object error)? onError, Function ()? onDone, bool cancelOnError = true});
47 ProxyAddress get address;
48 }
\ No newline at end of file
cw_core/lib/utils/proxy_socket/insecure.dart
+6 -6
@@ -10,15 +10,15 @@ class ProxySocketInsecure implements ProxySocket {
10
11 ProxySocketInsecure(this.socket);
12
13 - bool _isClosed = false;
13 + bool isClosed = false;
14
15 ProxyAddress get address => ProxyAddress(host: socket.remoteAddress.host, port: socket.remotePort);
16
17 @override
18 Future<void> close() async {
19 try {
20 - if (_isClosed) return;
21 - _isClosed = true;
20 + if (isClosed) return;
21 + isClosed = true;
22 return socket.close();
23 } catch (e) {
24 printV("ProxySocketInsecure: close: $e");
@@ -29,8 +29,8 @@ class ProxySocketInsecure implements ProxySocket {
29 @override
30 void destroy() async {
31 try {
32 - if (_isClosed) return;
33 - _isClosed = true;
32 + if (isClosed) return;
33 + isClosed = true;
34 socket.destroy();
35 } catch (e) {
36 printV("ProxySocketInsecure: destroy: $e");
@@ -41,7 +41,7 @@ class ProxySocketInsecure implements ProxySocket {
41 @override
42 void write(String data) {
43 try {
44 - if (_isClosed) {
44 + if (isClosed) {
45 printV("ProxySocketInsecure: write: socket is closed");
46 return;
47 }
cw_core/lib/utils/proxy_socket/secure.dart
+6 -6
@@ -8,7 +8,7 @@ import 'package:cw_core/utils/proxy_socket/abstract.dart';
8 class ProxySocketSecure implements ProxySocket {
9 final SecureSocket socket;
10
11 - bool _isClosed = false;
11 + bool isClosed = false;
12
13 ProxySocketSecure(this.socket);
14
@@ -17,8 +17,8 @@ class ProxySocketSecure implements ProxySocket {
17 @override
18 Future<void> close() async {
19 try {
20 - if (_isClosed) return;
21 - _isClosed = true;
20 + if (isClosed) return;
21 + isClosed = true;
22 return socket.close();
23 } catch (e) {
24 printV("ProxySocketSecure: close: $e");
@@ -29,8 +29,8 @@ class ProxySocketSecure implements ProxySocket {
29 @override
30 void destroy() async {
31 try {
32 - if (_isClosed) return;
33 - _isClosed = true;
32 + if (isClosed) return;
33 + isClosed = true;
34 socket.destroy();
35 } catch (e) {
36 printV("ProxySocketSecure: destroy: $e");
@@ -41,7 +41,7 @@ class ProxySocketSecure implements ProxySocket {
41 @override
42 void write(String data) {
43 try {
44 - if (_isClosed) {
44 + if (isClosed) {
45 printV("ProxySocketSecure: write: socket is closed");
46 return;
47 }
cw_core/lib/utils/proxy_socket/socks.dart
+4 -4
@@ -7,7 +7,7 @@ import 'package:socks_socket/socks_socket.dart';
7
8 class ProxySocketSocks implements ProxySocket {
9 final SOCKSSocket socket;
10 - bool _isClosed = false;
10 + bool isClosed = false;
11 ProxySocketSocks(this.socket);
12
13 @override
@@ -16,8 +16,8 @@ class ProxySocketSocks implements ProxySocket {
16 @override
17 Future<void> close() async {
18 try {
19 - if (_isClosed) return;
20 - _isClosed = true;
19 + if (isClosed) return;
20 + isClosed = true;
21 await socket.close();
22 } catch (e) {
23 printV("ProxySocketSocks: close: $e");
@@ -31,7 +31,7 @@ class ProxySocketSocks implements ProxySocket {
31 @override
32 void write(String data) {
33 try {
34 - if (_isClosed) {
34 + if (isClosed) {
35 printV("ProxySocketSocks: write: socket is closed");
36 return;
37 }