fix: Attempt to fix reconnection issues

Call _reconnectionPolicy.onSuccess when negotiations are done. Never
call onFailure directly; only ever call handleError.
This commit is contained in:
PapaTutuWawa 2023-01-14 12:39:55 +01:00
parent ce3ea656ad
commit 9baf1ed73c
2 changed files with 16 additions and 11 deletions

View File

@ -198,9 +198,6 @@ class XmppConnection {
// ignore: use_late_for_private_fields_and_variables // ignore: use_late_for_private_fields_and_variables
Completer<XmppConnectionResult>? _connectionCompleter; Completer<XmppConnectionResult>? _connectionCompleter;
/// Controls whether an XmppSocketClosureEvent triggers a reconnection.
bool _socketClosureTriggersReconnect = true;
/// Negotiators /// Negotiators
final Map<String, XmppFeatureNegotiatorBase> _featureNegotiators = {}; final Map<String, XmppFeatureNegotiatorBase> _featureNegotiators = {};
XmppFeatureNegotiatorBase? _currentNegotiator; XmppFeatureNegotiatorBase? _currentNegotiator;
@ -428,7 +425,6 @@ class XmppConnection {
} }
await _setConnectionState(XmppConnectionState.error); await _setConnectionState(XmppConnectionState.error);
await _resetIsConnectionRunning();
await _reconnectionPolicy.onFailure(); await _reconnectionPolicy.onFailure();
} }
@ -437,9 +433,9 @@ class XmppConnection {
if (event is XmppSocketErrorEvent) { if (event is XmppSocketErrorEvent) {
await handleError(SocketError(event)); await handleError(SocketError(event));
} else if (event is XmppSocketClosureEvent) { } else if (event is XmppSocketClosureEvent) {
if (_socketClosureTriggersReconnect) { if (!event.expected) {
_log.fine('Received XmppSocketClosureEvent. Reconnecting...'); _log.fine('Received unexpected XmppSocketClosureEvent. Reconnecting...');
await _reconnectionPolicy.onFailure(); await handleError(SocketError(XmppSocketErrorEvent(event)));
} else { } else {
_log.fine('Received XmppSocketClosureEvent. No reconnection attempt since _socketClosureTriggersReconnect is false...'); _log.fine('Received XmppSocketClosureEvent. No reconnection attempt since _socketClosureTriggersReconnect is false...');
} }
@ -850,6 +846,7 @@ class XmppConnection {
final result = await _currentNegotiator!.negotiate(nonza); final result = await _currentNegotiator!.negotiate(nonza);
if (result.isType<NegotiatorError>()) { if (result.isType<NegotiatorError>()) {
_log.severe('Negotiator returned an error'); _log.severe('Negotiator returned an error');
await _resetIsConnectionRunning();
await handleError(result.get<NegotiatorError>()); await handleError(result.get<NegotiatorError>());
return; return;
} }
@ -873,6 +870,8 @@ class XmppConnection {
if (_isMandatoryNegotiationDone(_streamFeatures) && !_isNegotiationPossible(_streamFeatures)) { if (_isMandatoryNegotiationDone(_streamFeatures) && !_isNegotiationPossible(_streamFeatures)) {
_log.finest('Negotiations done!'); _log.finest('Negotiations done!');
_updateRoutingState(RoutingState.handleStanzas); _updateRoutingState(RoutingState.handleStanzas);
await _reconnectionPolicy.onSuccess();
await _resetIsConnectionRunning();
await _onNegotiationsDone(); await _onNegotiationsDone();
} else { } else {
_currentNegotiator = getNextNegotiator(_streamFeatures); _currentNegotiator = getNextNegotiator(_streamFeatures);
@ -896,6 +895,8 @@ class XmppConnection {
_log.finest('Negotiations done!'); _log.finest('Negotiations done!');
_updateRoutingState(RoutingState.handleStanzas); _updateRoutingState(RoutingState.handleStanzas);
await _reconnectionPolicy.onSuccess();
await _resetIsConnectionRunning();
await _onNegotiationsDone(); await _onNegotiationsDone();
} else { } else {
_log.finest('Picking new negotiator...'); _log.finest('Picking new negotiator...');
@ -912,6 +913,8 @@ class XmppConnection {
_log.finest('Negotiator wants to skip the remaining negotiation... Negotiations (assumed) done!'); _log.finest('Negotiator wants to skip the remaining negotiation... Negotiations (assumed) done!');
_updateRoutingState(RoutingState.handleStanzas); _updateRoutingState(RoutingState.handleStanzas);
await _reconnectionPolicy.onSuccess();
await _resetIsConnectionRunning();
await _onNegotiationsDone(); await _onNegotiationsDone();
break; break;
} }
@ -1023,7 +1026,6 @@ class XmppConnection {
Future<void> _disconnect({required XmppConnectionState state, bool triggeredByUser = true}) async { Future<void> _disconnect({required XmppConnectionState state, bool triggeredByUser = true}) async {
_reconnectionPolicy.setShouldReconnect(false); _reconnectionPolicy.setShouldReconnect(false);
_socketClosureTriggersReconnect = false;
if (triggeredByUser) { if (triggeredByUser) {
getPresenceManager().sendUnavailablePresence(); getPresenceManager().sendUnavailablePresence();
@ -1079,7 +1081,6 @@ class XmppConnection {
} }
await _reconnectionPolicy.reset(); await _reconnectionPolicy.reset();
_socketClosureTriggersReconnect = true;
await _sendEvent(ConnectingEvent()); await _sendEvent(ConnectingEvent());
final smManager = getStreamManagementManager(); final smManager = getStreamManagementManager();

View File

@ -5,13 +5,17 @@ abstract class XmppSocketEvent {}
/// Triggered by the socket when an error occurs. /// Triggered by the socket when an error occurs.
class XmppSocketErrorEvent extends XmppSocketEvent { class XmppSocketErrorEvent extends XmppSocketEvent {
XmppSocketErrorEvent(this.error); XmppSocketErrorEvent(this.error);
final Object error; final Object error;
} }
/// Triggered when the socket is closed /// Triggered when the socket is closed
class XmppSocketClosureEvent extends XmppSocketEvent {} class XmppSocketClosureEvent extends XmppSocketEvent {
XmppSocketClosureEvent(this.expected);
/// Indicate that the socket did not close unexpectedly.
final bool expected;
}
/// This class is the base for a socket that XmppConnection can use. /// This class is the base for a socket that XmppConnection can use.
abstract class BaseSocketWrapper { abstract class BaseSocketWrapper {