|
@@ -36,11 +36,9 @@ class WsConnection implements IConnection {
|
|
|
|
|
|
Timer? _timer;
|
|
|
|
|
|
- WsConnection(
|
|
|
- this.host, {
|
|
|
- this.exceptionOccurred,
|
|
|
- this.statusChanged,
|
|
|
- }) {
|
|
|
+ WsConnection(this.host) {
|
|
|
+ exceptionOccurred = FEventHandler<Exception>();
|
|
|
+ statusChanged = FEventHandler<ConnectionStatus>();
|
|
|
messageReceived = FEventHandler<dynamic>();
|
|
|
}
|
|
|
|
|
@@ -54,55 +52,66 @@ class WsConnection implements IConnection {
|
|
|
bool get isKeepAlive => _keepAlive;
|
|
|
|
|
|
@override
|
|
|
- FEventHandler<Exception>? exceptionOccurred;
|
|
|
+ late final FEventHandler<Exception> exceptionOccurred;
|
|
|
|
|
|
@override
|
|
|
late final FEventHandler<dynamic> messageReceived;
|
|
|
|
|
|
@override
|
|
|
- FEventHandler<ConnectionStatus>? statusChanged;
|
|
|
+ late final FEventHandler<ConnectionStatus> statusChanged;
|
|
|
|
|
|
@override
|
|
|
Future<bool> connect() async {
|
|
|
logger.i("WsConnection is trying connect...");
|
|
|
_hasError = false;
|
|
|
_keepAlive = true;
|
|
|
- final uri = Uri.parse(host);
|
|
|
- _channel = WebSocketChannel.connect(uri);
|
|
|
- if (_channel == null) {
|
|
|
- logger.i("The ws connect failed.");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- final completer = Completer<bool>();
|
|
|
- Future.delayed(const Duration(milliseconds: 500), () {
|
|
|
- if (completer.isCompleted || _hasError) return;
|
|
|
+ try {
|
|
|
+ final uri = Uri.parse(host);
|
|
|
+ _channel = WebSocketChannel.connect(uri);
|
|
|
+
|
|
|
+ final connectResult = await _waitConnectWithTimeout(_channel!);
|
|
|
+ if (!connectResult) {
|
|
|
+ _updateStatus(ConnectionStatus.connectFailed);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
_updateStatus(ConnectionStatus.connected);
|
|
|
- completer.complete(true);
|
|
|
|
|
|
logger.i("The ws connection is connected.");
|
|
|
_startCheckConnection();
|
|
|
- });
|
|
|
|
|
|
- _channel!.stream.listen(
|
|
|
- (data) {
|
|
|
- messageReceived.emit(this, data);
|
|
|
- },
|
|
|
- onError: (error) {
|
|
|
- _hasError = true;
|
|
|
- _handleCancelOnError(error);
|
|
|
- try {
|
|
|
- if (!completer.isCompleted) {
|
|
|
- completer.complete(false);
|
|
|
- }
|
|
|
- } catch (e) {}
|
|
|
- },
|
|
|
- cancelOnError: true,
|
|
|
- onDone: () {},
|
|
|
- );
|
|
|
+ _channel!.stream.listen(
|
|
|
+ (data) {
|
|
|
+ messageReceived.emit(this, data);
|
|
|
+ },
|
|
|
+ onError: (error) {
|
|
|
+ _hasError = true;
|
|
|
+ _handleCancelOnError(error);
|
|
|
+ },
|
|
|
+ cancelOnError: true,
|
|
|
+ onDone: () {},
|
|
|
+ );
|
|
|
+ } catch (e) {
|
|
|
+ logger.e("WsConnection connect error.", e);
|
|
|
+ _updateStatus(ConnectionStatus.connectFailed);
|
|
|
+ _handleCancelOnError(e);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ Future<bool> _waitConnectWithTimeout(
|
|
|
+ WebSocketChannel channel, {
|
|
|
+ Duration timeLimit = const Duration(seconds: 3),
|
|
|
+ }) async {
|
|
|
+ Future<bool> wrapperFn() async {
|
|
|
+ await channel.ready;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
- return completer.future;
|
|
|
+ final result = await wrapperFn().timeout(timeLimit, onTimeout: () => false);
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
@override
|
|
@@ -123,9 +132,13 @@ class WsConnection implements IConnection {
|
|
|
}
|
|
|
|
|
|
void _updateStatus(ConnectionStatus value) {
|
|
|
- if (value != _status) {
|
|
|
- _status = value;
|
|
|
- statusChanged?.emit(this, value);
|
|
|
+ try {
|
|
|
+ if (value != _status) {
|
|
|
+ _status = value;
|
|
|
+ statusChanged?.emit(this, value);
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ //
|
|
|
}
|
|
|
}
|
|
|
|