diff --git a/app/lib/service/substrate_api/api.dart b/app/lib/service/substrate_api/api.dart index 7987a51ba..242349156 100644 --- a/app/lib/service/substrate_api/api.dart +++ b/app/lib/service/substrate_api/api.dart @@ -242,8 +242,13 @@ class Api { } class ReconnectingWsProvider extends Provider { - ReconnectingWsProvider(Uri url, {bool autoConnect = true}) : provider = WsProvider(url, autoConnect: autoConnect); + ReconnectingWsProvider(this.url, {bool autoConnect = true}) + : provider = WsProvider( + url, + autoConnect: autoConnect, + ); + final Uri url; WsProvider provider; Future connectToNewEndpoint(Uri url) async { @@ -256,26 +261,37 @@ class ReconnectingWsProvider extends Provider { if (isConnected()) { return Future.value(); } else { - return connect(); + // We want to use a new channel even if the channel exists but it was closed. + provider.channel = null; + provider = WsProvider(url, autoConnect: false); + return provider.connect(); } } @override Future disconnect() { - if (!isConnected()) { + // We only care if the channel is not equal to null. + // Because we still want the internal cleanup if + // the connection was closed from the other end. + if (provider.channel == null) { return Future.value(); } else { - return disconnect(); + return provider.disconnect(); } } @override bool isConnected() { - return provider.isConnected(); + // the `provider.isConnected()` check is wrong upstream. + // Hence, we implement it ourselves. + final channel = provider.channel; + return channel != null && channel.closeCode == null; } @override - Future send(String method, List params) { + Future send(String method, List params) async { + // Connect if disconnected + await connect(); return provider.send(method, params); } @@ -284,7 +300,9 @@ class ReconnectingWsProvider extends Provider { String method, List params, { FutureOr Function(String subscription)? onCancel, - }) { + }) async { + // Connect if disconnected + await connect(); return provider.subscribe(method, params, onCancel: onCancel); } }