From 3ae42be9d639593e5c39b38fd0a939de22a6d998 Mon Sep 17 00:00:00 2001 From: sahani-deriv Date: Thu, 3 Aug 2023 12:39:43 +0800 Subject: [PATCH 1/3] fix: connectivity ping issue --- lib/state/connection/connection_cubit.dart | 51 ++++++++++++---------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/lib/state/connection/connection_cubit.dart b/lib/state/connection/connection_cubit.dart index 4a655bb363..c47d4db6ab 100644 --- a/lib/state/connection/connection_cubit.dart +++ b/lib/state/connection/connection_cubit.dart @@ -32,13 +32,9 @@ class ConnectionCubit extends Cubit { _connectionInformation = connectionInformation; - if (_api is BinaryAPI) { - _setupConnectivityListener(); - } + _connect(_connectionInformation); _startKeepAliveTimer(); - - _connect(_connectionInformation); } final String _key = '${UniqueKey()}'; @@ -74,6 +70,9 @@ class ConnectionCubit extends Cubit { /// Gets app id of websocket. static String get appId => _connectionInformation.appId; + /// Streamsubscription for connectivity. + StreamSubscription? connectivitySubscription; + /// Reconnect to Websocket. Future reconnect({ConnectionInformation? connectionInformation}) async { emit(const ConnectionDisconnectedState()); @@ -122,26 +121,30 @@ class ConnectionCubit extends Cubit { } }, ); + + if (_api is BinaryAPI) { + _setupConnectivityListener(); + } } - void _setupConnectivityListener() => - Connectivity().onConnectivityChanged.listen( - (ConnectivityResult status) async { - final bool isConnectedToNetwork = - status == ConnectivityResult.mobile || - status == ConnectivityResult.wifi; - - if (isConnectedToNetwork) { - final bool isConnected = await _ping(); - - if (!isConnected) { - await reconnect(); - } - } else if (status == ConnectivityResult.none) { - emit(const ConnectionDisconnectedState()); + void _setupConnectivityListener() { + connectivitySubscription ??= Connectivity().onConnectivityChanged.listen( + (ConnectivityResult status) async { + final bool isConnectedToNetwork = status == ConnectivityResult.mobile || + status == ConnectivityResult.wifi; + + if (isConnectedToNetwork) { + final bool isConnected = await _ping(); + + if (!isConnected) { + await reconnect(); } - }, - ); + } else if (status == ConnectivityResult.none) { + emit(const ConnectionDisconnectedState()); + } + }, + ); + } void _startKeepAliveTimer() { if (_connectivityTimer == null || !_connectivityTimer!.isActive) { @@ -154,7 +157,6 @@ class ConnectionCubit extends Cubit { try { final PingResponse response = await PingResponse.pingMethod().timeout(_pingTimeout); - return response.ping == PingEnum.pong; } on Exception catch (_) { return false; @@ -164,7 +166,8 @@ class ConnectionCubit extends Cubit { @override Future close() { _connectivityTimer?.cancel(); - + connectivitySubscription?.cancel(); + connectivitySubscription = null; return super.close(); } } From e7a80e2ab0872ef278b94475aef2aa9b9ca24826 Mon Sep 17 00:00:00 2001 From: sahani-deriv Date: Thu, 3 Aug 2023 12:47:03 +0800 Subject: [PATCH 2/3] fix: BaseAPIException --- lib/api/response/p2p_ping_response_result.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/response/p2p_ping_response_result.dart b/lib/api/response/p2p_ping_response_result.dart index 02d97a4ccb..a82581922a 100644 --- a/lib/api/response/p2p_ping_response_result.dart +++ b/lib/api/response/p2p_ping_response_result.dart @@ -67,7 +67,7 @@ class P2pPingResponse extends P2pPingResponseModel { checkException( response: response, exceptionCreator: ({BaseExceptionModel? baseExceptionModel}) => - APIBaseException(baseExceptionModel: baseExceptionModel), + BaseAPIException(baseExceptionModel: baseExceptionModel), ); return response; From 10d2c682cdc7819b6606679927ae73f842ba3055 Mon Sep 17 00:00:00 2001 From: hamed-deriv <57184669+hamed-deriv@users.noreply.github.com> Date: Mon, 7 Aug 2023 10:06:39 +0800 Subject: [PATCH 3/3] hamed/refactor_connection_cubit --- example/ios/Flutter/AppFrameworkInfo.plist | 2 +- example/ios/Flutter/Flutter.podspec | 12 +-- example/ios/Podfile | 2 +- example/ios/Podfile.lock | 39 +++------ example/ios/Runner.xcodeproj/project.pbxproj | 40 ++++++---- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- example/ios/Runner/Info.plist | 4 + .../connection/api_manager/base_api.dart | 5 ++ .../connection/api_manager/binary_api.dart | 26 +++--- .../connection/api_manager/mock_api.dart | 6 ++ lib/state/connection/connection_cubit.dart | 80 +++++-------------- pubspec.yaml | 8 +- .../call_manager/base_call_manager_test.dart | 6 ++ 13 files changed, 106 insertions(+), 126 deletions(-) diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 6b4c0f78a7..4f8d4d2456 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 8.0 + 11.0 diff --git a/example/ios/Flutter/Flutter.podspec b/example/ios/Flutter/Flutter.podspec index 2c4421cfe5..29758b70d5 100644 --- a/example/ios/Flutter/Flutter.podspec +++ b/example/ios/Flutter/Flutter.podspec @@ -1,17 +1,17 @@ # -# NOTE: This podspec is NOT to be published. It is only used as a local source! -# This is a generated file; do not edit or check into version control. +# This podspec is NOT to be published. It is only used as a local source! +# This is a generated file; do not edit or check into version control. # Pod::Spec.new do |s| s.name = 'Flutter' s.version = '1.0.0' - s.summary = 'High-performance, high-fidelity mobile apps.' - s.homepage = 'https://flutter.io' - s.license = { :type => 'MIT' } + s.summary = 'A UI toolkit for beautiful and fast apps.' + s.homepage = 'https://flutter.dev' + s.license = { :type => 'BSD' } s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } - s.ios.deployment_target = '8.0' + s.ios.deployment_target = '11.0' # Framework linking is handled by Flutter tooling, not CocoaPods. # Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs. s.vendored_frameworks = 'path/to/nothing' diff --git a/example/ios/Podfile b/example/ios/Podfile index 1e8c3c90a5..88359b225f 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '9.0' +# platform :ios, '11.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 9c4013933b..971f498761 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,47 +1,34 @@ PODS: - - connectivity (0.0.1): - - Flutter - - Reachability - - device_info (0.0.1): + - device_info_plus (0.0.1): - Flutter - Flutter (1.0.0) - flutter_deriv_api (0.0.1): - Flutter - - package_info (0.0.1): + - package_info_plus (0.4.5): - Flutter - - Reachability (3.2) DEPENDENCIES: - - connectivity (from `.symlinks/plugins/connectivity/ios`) - - device_info (from `.symlinks/plugins/device_info/ios`) + - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - Flutter (from `Flutter`) - flutter_deriv_api (from `.symlinks/plugins/flutter_deriv_api/ios`) - - package_info (from `.symlinks/plugins/package_info/ios`) - -SPEC REPOS: - trunk: - - Reachability + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) EXTERNAL SOURCES: - connectivity: - :path: ".symlinks/plugins/connectivity/ios" - device_info: - :path: ".symlinks/plugins/device_info/ios" + device_info_plus: + :path: ".symlinks/plugins/device_info_plus/ios" Flutter: :path: Flutter flutter_deriv_api: :path: ".symlinks/plugins/flutter_deriv_api/ios" - package_info: - :path: ".symlinks/plugins/package_info/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" SPEC CHECKSUMS: - connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 - device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 - Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c + device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 flutter_deriv_api: 9e29abd7cc5091b72303f9c8be549618415f1437 - package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 - Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 + package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e -PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c +PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 -COCOAPODS: 1.10.1 +COCOAPODS: 1.12.1 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 6c53661486..f973131b2d 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -164,7 +164,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1300; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -213,19 +213,15 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework", - "${BUILT_PRODUCTS_DIR}/connectivity/connectivity.framework", - "${BUILT_PRODUCTS_DIR}/device_info/device_info.framework", + "${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework", "${BUILT_PRODUCTS_DIR}/flutter_deriv_api/flutter_deriv_api.framework", - "${BUILT_PRODUCTS_DIR}/package_info/package_info.framework", + "${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_deriv_api.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -234,10 +230,12 @@ }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -248,6 +246,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -357,7 +356,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -379,7 +378,10 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -439,7 +441,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -488,7 +490,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -511,7 +513,10 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -538,7 +543,10 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a28140cfdb..3db53b6e1f 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ UIViewControllerBasedStatusBarAppearance + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + diff --git a/lib/services/connection/api_manager/base_api.dart b/lib/services/connection/api_manager/base_api.dart index 8cc480351a..dda5280269 100644 --- a/lib/services/connection/api_manager/base_api.dart +++ b/lib/services/connection/api_manager/base_api.dart @@ -1,3 +1,5 @@ +import 'package:deriv_web_socket_client/deriv_web_socket_client.dart'; + import 'package:flutter_deriv_api/api/models/enums.dart'; import 'package:flutter_deriv_api/basic_api/generated/forget_all_receive.dart'; import 'package:flutter_deriv_api/basic_api/generated/forget_receive.dart'; @@ -29,6 +31,9 @@ abstract class BaseAPI { bool printResponse, }); + /// Gets the current connection status. + Stream get connectionStatus; + /// Adds request to stream channel. void addToChannel(Map request); diff --git a/lib/services/connection/api_manager/binary_api.dart b/lib/services/connection/api_manager/binary_api.dart index 896583b8f6..a8ba2a1b3b 100644 --- a/lib/services/connection/api_manager/binary_api.dart +++ b/lib/services/connection/api_manager/binary_api.dart @@ -1,10 +1,11 @@ import 'dart:async'; import 'dart:convert'; import 'dart:developer' as dev; -import 'dart:io'; +import 'dart:io' as io; import 'package:flutter/widgets.dart'; -import 'package:web_socket_channel/io.dart'; + +import 'package:deriv_web_socket_client/deriv_web_socket_client.dart' as ws; import 'package:flutter_deriv_api/api/models/enums.dart'; import 'package:flutter_deriv_api/basic_api/generated/forget_all_receive.dart'; @@ -27,12 +28,11 @@ class BinaryAPI extends BaseAPI { : super(key: key ?? '${UniqueKey()}', enableDebug: enableDebug); static const Duration _disconnectTimeOut = Duration(seconds: 5); - static const Duration _websocketConnectTimeOut = Duration(seconds: 10); /// Represents the active websocket connection. /// /// This is used to send and receive data from the websocket server. - IOWebSocketChannel? _webSocketChannel; + ws.WebSocket? _webSocket; /// Stream subscription to API data. StreamSubscription?>? _webSocketListener; @@ -49,6 +49,9 @@ class BinaryAPI extends BaseAPI { /// Gets API subscription history. CallHistory? get subscriptionHistory => _subscriptionManager?.callHistory; + @override + Stream get connectionStatus => _webSocket!.connection; + @override Future connect( ConnectionInformation? connectionInformation, { @@ -76,12 +79,9 @@ class BinaryAPI extends BaseAPI { await _setUserAgent(); // Initialize connection to websocket server. - _webSocketChannel = IOWebSocketChannel.connect( - '$uri', - pingInterval: _websocketConnectTimeOut, - ); + _webSocket = ws.WebSocket(uri); - _webSocketListener = _webSocketChannel?.stream + _webSocketListener = _webSocket?.messages .map?>((Object? result) => jsonDecode('$result')) .listen( (Map? message) { @@ -117,7 +117,7 @@ class BinaryAPI extends BaseAPI { @override void addToChannel(Map request) { try { - _webSocketChannel?.sink.add(utf8.encode(jsonEncode(request))); + _webSocket?.send(utf8.encode(jsonEncode(request))); // ignore: avoid_catches_without_on_clauses } catch (error) { _logDebugInfo('error while adding to channel.', error: error); @@ -167,7 +167,7 @@ class BinaryAPI extends BaseAPI { try { await _webSocketListener?.cancel(); - await _webSocketChannel?.sink.close().timeout( + await _webSocket?.close().timeout( _disconnectTimeOut, onTimeout: () => throw TimeoutException('Could not close sink.'), ); @@ -176,7 +176,7 @@ class BinaryAPI extends BaseAPI { _logDebugInfo('disconnect error.', error: e); } finally { _webSocketListener = null; - _webSocketChannel = null; + _webSocket = null; } } @@ -228,7 +228,7 @@ class BinaryAPI extends BaseAPI { final String userAgent = await getUserAgent(); if (userAgent.isNotEmpty) { - WebSocket.userAgent = userAgent; + io.WebSocket.userAgent = userAgent; } } diff --git a/lib/services/connection/api_manager/mock_api.dart b/lib/services/connection/api_manager/mock_api.dart index 8f51940748..58be6f335d 100644 --- a/lib/services/connection/api_manager/mock_api.dart +++ b/lib/services/connection/api_manager/mock_api.dart @@ -3,6 +3,8 @@ import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:deriv_web_socket_client/deriv_web_socket_client.dart' as ws; + import 'package:flutter_deriv_api/api/models/enums.dart'; import 'package:flutter_deriv_api/basic_api/generated/forget_all_receive.dart'; import 'package:flutter_deriv_api/basic_api/generated/forget_receive.dart'; @@ -112,6 +114,10 @@ class MockAPI extends BaseAPI { /// Initializes MockAPI({String? key}) : super(key: key ?? '${UniqueKey()}'); + @override + Stream get connectionStatus => + Stream.value(const ws.ConnectedState()); + @override Future connect( ConnectionInformation? connectionInformation, { diff --git a/lib/state/connection/connection_cubit.dart b/lib/state/connection/connection_cubit.dart index c47d4db6ab..6698bfbe08 100644 --- a/lib/state/connection/connection_cubit.dart +++ b/lib/state/connection/connection_cubit.dart @@ -1,13 +1,13 @@ import 'dart:async'; import 'dart:developer' as dev; -import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:deriv_web_socket_client/deriv_web_socket_client.dart' as ws; + import 'package:flutter_deriv_api/api/api_initializer.dart'; -import 'package:flutter_deriv_api/api/response/ping_response_result.dart'; import 'package:flutter_deriv_api/services/connection/api_manager/base_api.dart'; import 'package:flutter_deriv_api/services/connection/api_manager/binary_api.dart'; import 'package:flutter_deriv_api/services/connection/api_manager/connection_information.dart'; @@ -33,8 +33,6 @@ class ConnectionCubit extends Cubit { _connectionInformation = connectionInformation; _connect(_connectionInformation); - - _startKeepAliveTimer(); } final String _key = '${UniqueKey()}'; @@ -51,13 +49,6 @@ class ConnectionCubit extends Cubit { /// Default value is `false`. final bool printResponse; - // In some devices like Samsung J6 or Huawei Y7, the call manager doesn't response to the ping call less than 5 sec. - final Duration _pingTimeout = const Duration(seconds: 5); - - final Duration _connectivityCheckInterval = const Duration(seconds: 5); - - Timer? _connectivityTimer; - static late ConnectionInformation _connectionInformation; /// Gets connection information of WebSocket (endpoint, brand, appId). @@ -70,9 +61,6 @@ class ConnectionCubit extends Cubit { /// Gets app id of websocket. static String get appId => _connectionInformation.appId; - /// Streamsubscription for connectivity. - StreamSubscription? connectivitySubscription; - /// Reconnect to Websocket. Future reconnect({ConnectionInformation? connectionInformation}) async { emit(const ConnectionDisconnectedState()); @@ -93,7 +81,7 @@ class ConnectionCubit extends Cubit { emit(const ConnectionConnectingState()); try { - await _api!.disconnect().timeout(_pingTimeout); + await _api!.disconnect(); } on Exception catch (e) { dev.log('$runtimeType disconnect exception: $e', error: e); @@ -122,52 +110,24 @@ class ConnectionCubit extends Cubit { }, ); - if (_api is BinaryAPI) { - _setupConnectivityListener(); - } + _setupConnectivityListener(); } - void _setupConnectivityListener() { - connectivitySubscription ??= Connectivity().onConnectivityChanged.listen( - (ConnectivityResult status) async { - final bool isConnectedToNetwork = status == ConnectivityResult.mobile || - status == ConnectivityResult.wifi; - - if (isConnectedToNetwork) { - final bool isConnected = await _ping(); - - if (!isConnected) { - await reconnect(); - } - } else if (status == ConnectivityResult.none) { - emit(const ConnectionDisconnectedState()); + void _setupConnectivityListener() => + _api?.connectionStatus.listen((ws.ConnectionState state) { + switch (state) { + case ws.ConnectedState(): + case ws.ReconnectedState(): + emit(const ConnectionConnectedState()); + break; + case ws.DisconnectedState(): + case ws.DisconnectingState(): + emit(const ConnectionDisconnectedState()); + break; + case ws.ConnectingState(): + case ws.ReconnectingState(): + emit(const ConnectionConnectingState()); + break; } - }, - ); - } - - void _startKeepAliveTimer() { - if (_connectivityTimer == null || !_connectivityTimer!.isActive) { - _connectivityTimer = - Timer.periodic(_connectivityCheckInterval, (Timer timer) => _ping()); - } - } - - Future _ping() async { - try { - final PingResponse response = - await PingResponse.pingMethod().timeout(_pingTimeout); - return response.ping == PingEnum.pong; - } on Exception catch (_) { - return false; - } - } - - @override - Future close() { - _connectivityTimer?.cancel(); - connectivitySubscription?.cancel(); - connectivitySubscription = null; - return super.close(); - } + }); } diff --git a/pubspec.yaml b/pubspec.yaml index 9612ac8ed5..ea32ef1c0d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,6 +20,12 @@ dependencies: path: packages/deriv_dependency_injector ref: flutter-version-3 + deriv_web_socket_client: + git: + url: git@github.com:regentmarkets/flutter-deriv-packages.git + path: packages/deriv_web_socket_client + ref: 8cc61cc301f259f2debd0cace29cee79392735ef + build: ^2.3.1 dart_style: ^2.3.0 equatable: ^2.0.3 @@ -29,10 +35,8 @@ dependencies: meta: ^1.8.0 recase: ^4.0.0 rxdart: ^0.27.7 - web_socket_channel: ^2.3.0 device_info_plus: ^8.1.0 package_info_plus: ^3.0.3 - connectivity_plus: ^3.0.3 dev_dependencies: flutter_test: diff --git a/test/services/call_manager/base_call_manager_test.dart b/test/services/call_manager/base_call_manager_test.dart index 5ba12de77b..7c3d94d331 100644 --- a/test/services/call_manager/base_call_manager_test.dart +++ b/test/services/call_manager/base_call_manager_test.dart @@ -2,6 +2,8 @@ import 'dart:async'; import 'package:test/test.dart'; +import 'package:deriv_web_socket_client/deriv_web_socket_client.dart' as ws; + import 'package:flutter_deriv_api/api/models/enums.dart'; import 'package:flutter_deriv_api/basic_api/generated/forget_all_receive.dart'; import 'package:flutter_deriv_api/basic_api/generated/forget_receive.dart'; @@ -56,6 +58,10 @@ class MockCallManager extends BaseCallManager { } class MockAPI implements BaseAPI { + @override + Stream get connectionStatus => + Stream.value(const ws.ConnectedState()); + @override void addToChannel(Map request) {}