feat(core): Merge connect and connectAwaitable
This commit is contained in:
parent
976c0040b5
commit
25c778965c
@ -24,6 +24,7 @@ import 'package:moxxmpp/src/settings.dart';
|
||||
import 'package:moxxmpp/src/socket.dart';
|
||||
import 'package:moxxmpp/src/stanza.dart';
|
||||
import 'package:moxxmpp/src/stringxml.dart';
|
||||
import 'package:moxxmpp/src/types/result.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0198/negotiator.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0198/xep_0198.dart';
|
||||
@ -90,6 +91,32 @@ class XmppConnectionResult {
|
||||
final XmppError? error;
|
||||
}
|
||||
|
||||
/// The reason a call to [XmppConnection.connect] failed.
|
||||
abstract class XmppConnectionError {}
|
||||
|
||||
/// Returned by [XmppConnection.connect] when a connection is already active.
|
||||
class ConnectionAlreadyRunningError extends XmppConnectionError {}
|
||||
|
||||
/// Returned by [XmppConnection.connect] when a negotiator returned an unrecoverable
|
||||
/// error. Only returned when waitUntilLogin is true.
|
||||
class NegotiatorReturnedError extends XmppConnectionError {
|
||||
NegotiatorReturnedError(this.error);
|
||||
|
||||
/// The error returned by the negotiator.
|
||||
final NegotiatorError error;
|
||||
}
|
||||
|
||||
class StreamFailureError extends XmppConnectionError {
|
||||
StreamFailureError(this.error);
|
||||
|
||||
/// The error that causes a connection failure.
|
||||
final XmppError error;
|
||||
}
|
||||
|
||||
/// Returned by [XmppConnection.connect] when no connection could
|
||||
/// be established.
|
||||
class NoConnectionPossibleError extends XmppConnectionError {}
|
||||
|
||||
/// This class is a connection to the server.
|
||||
class XmppConnection {
|
||||
XmppConnection(
|
||||
@ -180,7 +207,7 @@ class XmppConnection {
|
||||
|
||||
/// Completers for certain actions
|
||||
// ignore: use_late_for_private_fields_and_variables
|
||||
Completer<XmppConnectionResult>? _connectionCompleter;
|
||||
Completer<Result<bool, XmppConnectionError>>? _connectionCompleter;
|
||||
|
||||
/// Negotiators
|
||||
final Map<String, XmppFeatureNegotiatorBase> _featureNegotiators = {};
|
||||
@ -198,6 +225,9 @@ class XmppConnection {
|
||||
bool _isConnectionRunning = false;
|
||||
final Lock _connectionRunningLock = Lock();
|
||||
|
||||
/// Flag indicating whether reconnection should be enabled after a successful connection.
|
||||
bool _enableReconnectOnSuccess = false;
|
||||
|
||||
/// Enters the critical section for accessing [XmppConnection._isConnectionRunning]
|
||||
/// and does the following:
|
||||
/// - if _isConnectionRunning is false, set it to true and return false.
|
||||
@ -404,9 +434,10 @@ class XmppConnection {
|
||||
state: XmppConnectionState.error,
|
||||
);
|
||||
_connectionCompleter?.complete(
|
||||
XmppConnectionResult(
|
||||
false,
|
||||
error: error,
|
||||
Result(
|
||||
StreamFailureError(
|
||||
error,
|
||||
),
|
||||
),
|
||||
);
|
||||
_connectionCompleter = null;
|
||||
@ -859,8 +890,13 @@ class XmppConnection {
|
||||
await _resetIsConnectionRunning();
|
||||
await _setConnectionState(XmppConnectionState.connected);
|
||||
|
||||
// Enable reconnections
|
||||
if (_enableReconnectOnSuccess) {
|
||||
await _reconnectionPolicy.setShouldReconnect(true);
|
||||
}
|
||||
|
||||
// Resolve the connection completion future
|
||||
_connectionCompleter?.complete(const XmppConnectionResult(true));
|
||||
_connectionCompleter?.complete(const Result(true));
|
||||
_connectionCompleter = null;
|
||||
|
||||
// Tell consumers of the event stream that we're done with stream feature
|
||||
@ -1112,45 +1148,26 @@ class XmppConnection {
|
||||
);
|
||||
}
|
||||
|
||||
/// Like [connect] but the Future resolves when the resource binding is either done or
|
||||
/// SASL has failed.
|
||||
Future<XmppConnectionResult> connectAwaitable({
|
||||
String? lastResource,
|
||||
bool waitForConnection = false,
|
||||
}) async {
|
||||
_runPreConnectionAssertions();
|
||||
await _resetIsConnectionRunning();
|
||||
_connectionCompleter = Completer();
|
||||
_log.finest('Calling connect() from connectAwaitable');
|
||||
await connect(
|
||||
lastResource: lastResource,
|
||||
waitForConnection: waitForConnection,
|
||||
shouldReconnect: false,
|
||||
);
|
||||
return _connectionCompleter!.future;
|
||||
}
|
||||
|
||||
/// Start the connection process using the provided connection settings.
|
||||
Future<void> connect({
|
||||
Future<Result<bool, XmppConnectionError>> _connectImpl({
|
||||
String? lastResource,
|
||||
bool waitForConnection = false,
|
||||
bool shouldReconnect = true,
|
||||
bool waitUntilLogin = false,
|
||||
bool enableReconnectOnSuccess = true,
|
||||
}) async {
|
||||
if (_connectionState != XmppConnectionState.notConnected &&
|
||||
_connectionState != XmppConnectionState.error) {
|
||||
_log.fine(
|
||||
'Cancelling this connection attempt as one appears to be already running.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
_runPreConnectionAssertions();
|
||||
await _resetIsConnectionRunning();
|
||||
|
||||
if (waitUntilLogin) {
|
||||
_log.finest('Setting up completer for awaiting completed login');
|
||||
_connectionCompleter = Completer();
|
||||
}
|
||||
|
||||
if (lastResource != null) {
|
||||
setResource(lastResource);
|
||||
}
|
||||
|
||||
_enableReconnectOnSuccess = enableReconnectOnSuccess;
|
||||
if (shouldReconnect) {
|
||||
await _reconnectionPolicy.setShouldReconnect(true);
|
||||
}
|
||||
@ -1182,6 +1199,8 @@ class XmppConnection {
|
||||
);
|
||||
if (!result) {
|
||||
await handleError(NoConnectionError());
|
||||
|
||||
return Result(NoConnectionPossibleError());
|
||||
} else {
|
||||
await _reconnectionPolicy.onSuccess();
|
||||
_log.fine('Preparing the internal state for a connection attempt');
|
||||
@ -1190,6 +1209,66 @@ class XmppConnection {
|
||||
_updateRoutingState(RoutingState.negotiating);
|
||||
_isAuthenticated = false;
|
||||
_sendStreamHeader();
|
||||
|
||||
if (waitUntilLogin) {
|
||||
return _connectionCompleter!.future;
|
||||
} else {
|
||||
return const Result(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Start the connection process using the provided connection settings.
|
||||
///
|
||||
/// If [lastResource] is set, then its value is used as the connection's resource.
|
||||
/// Useful for stream resumption.
|
||||
///
|
||||
/// [shouldReconnect] indicates whether the reconnection attempts should be
|
||||
/// automatically performed after a fatal failure of any kind occurs.
|
||||
///
|
||||
/// [waitForConnection] indicates whether the connection should wait for the "go"
|
||||
/// signal from a registered connectivity manager.
|
||||
///
|
||||
/// If [waitUntilLogin] is set to true, the future will resolve when either
|
||||
/// the connection has been successfully established (authentication included) or
|
||||
/// a failure occured. If set to false, then the future will immediately resolve
|
||||
/// to false.
|
||||
///
|
||||
/// [enableReconnectOnSuccess] indicates that automatic reconnection is to be
|
||||
/// enabled once the connection has been successfully established.
|
||||
Future<Result<bool, XmppConnectionError>> connect({
|
||||
String? lastResource,
|
||||
bool? shouldReconnect,
|
||||
bool waitForConnection = false,
|
||||
bool waitUntilLogin = false,
|
||||
bool enableReconnectOnSuccess = true,
|
||||
}) async {
|
||||
if (_connectionState != XmppConnectionState.notConnected &&
|
||||
_connectionState != XmppConnectionState.error) {
|
||||
_log.fine(
|
||||
'Cancelling this connection attempt as one appears to be already running.',
|
||||
);
|
||||
return Future.value(
|
||||
Result(
|
||||
ConnectionAlreadyRunningError(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final result = _connectImpl(
|
||||
lastResource: lastResource,
|
||||
shouldReconnect: shouldReconnect ?? !waitUntilLogin,
|
||||
waitForConnection: waitForConnection,
|
||||
enableReconnectOnSuccess: enableReconnectOnSuccess,
|
||||
);
|
||||
if (waitUntilLogin) {
|
||||
return result;
|
||||
} else {
|
||||
return Future.value(
|
||||
const Result(
|
||||
false,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user