Skip to content

Commit bf57f53

Browse files
authored
hamed/add_debug_mode_to_websocket_connection (#250)
- add debug mode to websocket connection
1 parent 9d77e36 commit bf57f53

File tree

4 files changed

+62
-45
lines changed

4 files changed

+62
-45
lines changed

lib/services/connection/api_manager/base_api.dart

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import 'package:flutter/material.dart';
21
import 'package:flutter_deriv_api/api/models/enums.dart';
32
import 'package:flutter_deriv_api/basic_api/generated/forget_all_receive.dart';
43
import 'package:flutter_deriv_api/basic_api/generated/forget_receive.dart';
@@ -8,15 +7,18 @@ import 'package:flutter_deriv_api/services/connection/api_manager/connection_inf
87
import 'package:flutter_deriv_api/services/connection/call_manager/base_call_manager.dart';
98

109
/// Callbacks for websocket connection.
11-
typedef ConnectionCallback = void Function(UniqueKey uniqueKey);
10+
typedef ConnectionCallback = void Function(String key);
1211

1312
/// Base class for handling API connection and calling APIs.
1413
abstract class BaseAPI {
1514
/// Initializes base api.
16-
BaseAPI({required this.uniqueKey});
15+
BaseAPI({required this.key, this.enableDebug = false});
1716

18-
/// A key to check the `onDone` function is called from the same instance.
19-
final UniqueKey uniqueKey;
17+
/// A key to check the connect callback function is called from the same instance.
18+
final String key;
19+
20+
/// A flag to enable debug mode.
21+
final bool enableDebug;
2022

2123
/// Connects to API.
2224
Future<void> connect(

lib/services/connection/api_manager/binary_api.dart

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,16 @@ import 'package:flutter_deriv_api/services/connection/call_manager/subscription_
2222

2323
/// This class is for handling Binary API connection and calling Binary APIs.
2424
class BinaryAPI extends BaseAPI {
25-
/// Initializes binary api.
26-
BinaryAPI({UniqueKey? uniqueKey})
27-
: super(uniqueKey: uniqueKey ?? UniqueKey());
25+
/// Initializes [BinaryAPI] instance.
26+
BinaryAPI({String? key, bool enableDebug = false})
27+
: super(key: key ?? '${UniqueKey()}', enableDebug: enableDebug);
2828

2929
static const Duration _disconnectTimeOut = Duration(seconds: 5);
3030
static const Duration _websocketConnectTimeOut = Duration(seconds: 10);
3131

32-
/// Represents the active web socket connection.
32+
/// Represents the active websocket connection.
33+
///
34+
/// This is used to send and receive data from the websocket server.
3335
IOWebSocketChannel? _webSocketChannel;
3436

3537
/// Stream subscription to API data.
@@ -69,11 +71,11 @@ class BinaryAPI extends BaseAPI {
6971
},
7072
);
7173

72-
dev.log('$runtimeType $uniqueKey connecting to $uri.');
74+
_logDebugInfo('connecting to $uri.');
7375

7476
await _setUserAgent();
7577

76-
// Initialize connection to web socket server.
78+
// Initialize connection to websocket server.
7779
_webSocketChannel = IOWebSocketChannel.connect(
7880
'$uri',
7981
pingInterval: _websocketConnectTimeOut,
@@ -83,27 +85,28 @@ class BinaryAPI extends BaseAPI {
8385
.map<Map<String, dynamic>?>((Object? result) => jsonDecode('$result'))
8486
.listen(
8587
(Map<String, dynamic>? message) {
86-
onOpen?.call(uniqueKey);
88+
onOpen?.call(key);
8789

8890
if (message != null) {
8991
_handleResponse(message, printResponse: printResponse);
9092
}
9193
},
9294
onDone: () async {
93-
dev.log('$runtimeType $uniqueKey web socket is closed.');
95+
_logDebugInfo('the websocket is closed.');
9496

95-
onDone?.call(uniqueKey);
97+
onDone?.call(key);
9698
},
9799
onError: (Object error) {
98-
dev.log(
99-
'$runtimeType $uniqueKey the web socket connection is closed: $error.',
100+
_logDebugInfo(
101+
'the websocket connection is closed with error.',
102+
error: error,
100103
);
101104

102-
onError?.call(uniqueKey);
105+
onError?.call(key);
103106
},
104107
);
105108

106-
dev.log('$runtimeType $uniqueKey send initial message.');
109+
_logDebugInfo('send initial message.');
107110
}
108111

109112
void _resetCallManagers() {
@@ -116,8 +119,8 @@ class BinaryAPI extends BaseAPI {
116119
try {
117120
_webSocketChannel?.sink.add(utf8.encode(jsonEncode(request)));
118121
// ignore: avoid_catches_without_on_clauses
119-
} catch (e) {
120-
dev.log('$runtimeType $uniqueKey error while adding to channel: $e');
122+
} catch (error) {
123+
_logDebugInfo('error while adding to channel.', error: error);
121124
}
122125
}
123126

@@ -170,7 +173,7 @@ class BinaryAPI extends BaseAPI {
170173
);
171174
// ignore: avoid_catches_without_on_clauses
172175
} catch (e) {
173-
dev.log('$runtimeType $uniqueKey disconnect error', error: e);
176+
_logDebugInfo('disconnect error.', error: e);
174177
} finally {
175178
_webSocketListener = null;
176179
_webSocketChannel = null;
@@ -184,21 +187,19 @@ class BinaryAPI extends BaseAPI {
184187
required bool printResponse,
185188
}) {
186189
try {
187-
dev.log('$runtimeType $uniqueKey web socket is connected.');
190+
_logDebugInfo('the websocket is connected.');
188191

189192
// Make sure that the received message is a map and it's parsable otherwise it throws an exception.
190193
final Map<String, dynamic> message = Map<String, dynamic>.from(response);
191194

192195
if (printResponse) {
193-
dev.log('$runtimeType $uniqueKey api response: $message.');
196+
_logDebugInfo('api response: $message.');
194197
}
195198

196199
if (message.containsKey('req_id')) {
197200
final int requestId = message['req_id'];
198201

199-
if (printResponse) {
200-
dev.log('$runtimeType $uniqueKey have request id: $requestId.');
201-
}
202+
_logDebugInfo('have request id: $requestId.');
202203

203204
if (_callManager?.contains(requestId) ?? false) {
204205
_callManager!.handleResponse(
@@ -211,18 +212,15 @@ class BinaryAPI extends BaseAPI {
211212
response: message,
212213
);
213214
} else {
214-
dev.log(
215+
_logDebugInfo(
215216
'$runtimeType $requestId, does not match anything in our pending queue.',
216217
);
217218
}
218219
} else {
219-
dev.log('$runtimeType $uniqueKey no req_id, ignoring.');
220+
_logDebugInfo('no req_id, ignoring.');
220221
}
221222
} on Exception catch (e) {
222-
dev.log(
223-
'$runtimeType $uniqueKey failed to process $response - $e',
224-
error: e,
225-
);
223+
_logDebugInfo('failed to process $response.', error: e);
226224
}
227225
}
228226

@@ -233,4 +231,10 @@ class BinaryAPI extends BaseAPI {
233231
WebSocket.userAgent = userAgent;
234232
}
235233
}
234+
235+
void _logDebugInfo(String message, {Object? error}) {
236+
if (enableDebug) {
237+
dev.log('$runtimeType $key $message', error: error);
238+
}
239+
}
236240
}

lib/services/connection/api_manager/mock_api.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:async';
22
import 'dart:convert';
33

44
import 'package:flutter/material.dart';
5+
56
import 'package:flutter_deriv_api/api/models/enums.dart';
67
import 'package:flutter_deriv_api/basic_api/generated/forget_all_receive.dart';
78
import 'package:flutter_deriv_api/basic_api/generated/forget_receive.dart';
@@ -109,7 +110,7 @@ import 'mock_data/user/verify_email_response.dart';
109110
/// This class is for handling mock API connection and calling mock APIs
110111
class MockAPI extends BaseAPI {
111112
/// Initializes
112-
MockAPI({UniqueKey? uniqueKey}) : super(uniqueKey: uniqueKey ?? UniqueKey());
113+
MockAPI({String? key}) : super(key: key ?? '${UniqueKey()}');
113114

114115
@override
115116
Future<void> connect(

lib/state/connection/connection_cubit.dart

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ class ConnectionCubit extends Cubit<ConnectionState> {
2121
ConnectionCubit(
2222
ConnectionInformation connectionInformation, {
2323
BaseAPI? api,
24+
this.enableDebug = false,
2425
this.printResponse = false,
2526
}) : super(const ConnectionInitialState()) {
26-
APIInitializer().initialize(api: api ?? BinaryAPI(uniqueKey: _uniqueKey));
27+
APIInitializer().initialize(
28+
api: api ?? BinaryAPI(key: _key, enableDebug: enableDebug),
29+
);
2730

2831
_api = Injector()<BaseAPI>();
2932

@@ -38,13 +41,20 @@ class ConnectionCubit extends Cubit<ConnectionState> {
3841
_connect(_connectionInformation);
3942
}
4043

41-
/// Prints API response to console.
42-
final bool printResponse;
43-
44-
final UniqueKey _uniqueKey = UniqueKey();
44+
final String _key = '${UniqueKey()}';
4545

4646
late final BaseAPI? _api;
4747

48+
/// Enables debug mode.
49+
///
50+
/// Default value is `false`.
51+
final bool enableDebug;
52+
53+
/// Prints API response to console, only works if [enableDebug] is `true`.
54+
///
55+
/// Default value is `false`.
56+
final bool printResponse;
57+
4858
// In some devices like Samsung J6 or Huawei Y7, the call manager doesn't response to the ping call less than 5 sec.
4959
final Duration _pingTimeout = const Duration(seconds: 5);
5060

@@ -95,21 +105,21 @@ class ConnectionCubit extends Cubit<ConnectionState> {
95105

96106
await _api!.connect(
97107
_connectionInformation,
98-
printResponse: printResponse,
99-
onOpen: (UniqueKey uniqueKey) {
100-
if (_uniqueKey == uniqueKey) {
108+
printResponse: enableDebug && printResponse,
109+
onOpen: (String key) {
110+
if (_key == key) {
101111
emit(const ConnectionConnectedState());
102112
}
103113
},
104-
onDone: (UniqueKey uniqueKey) async {
105-
if (_uniqueKey == uniqueKey) {
114+
onDone: (String key) async {
115+
if (_key == key) {
106116
await _api!.disconnect();
107117

108118
emit(const ConnectionDisconnectedState());
109119
}
110120
},
111-
onError: (UniqueKey uniqueKey) {
112-
if (_uniqueKey == uniqueKey) {
121+
onError: (String key) {
122+
if (_key == key) {
113123
emit(const ConnectionDisconnectedState());
114124
}
115125
},

0 commit comments

Comments
 (0)