diff --git a/packages/moxxmpp/lib/src/connection.dart b/packages/moxxmpp/lib/src/connection.dart index d6dc14a..ff17ba1 100644 --- a/packages/moxxmpp/lib/src/connection.dart +++ b/packages/moxxmpp/lib/src/connection.dart @@ -198,9 +198,6 @@ class XmppConnection { // ignore: use_late_for_private_fields_and_variables Completer? _connectionCompleter; - /// Controls whether an XmppSocketClosureEvent triggers a reconnection. - bool _socketClosureTriggersReconnect = true; - /// Negotiators final Map _featureNegotiators = {}; XmppFeatureNegotiatorBase? _currentNegotiator; @@ -428,7 +425,6 @@ class XmppConnection { } await _setConnectionState(XmppConnectionState.error); - await _resetIsConnectionRunning(); await _reconnectionPolicy.onFailure(); } @@ -437,9 +433,9 @@ class XmppConnection { if (event is XmppSocketErrorEvent) { await handleError(SocketError(event)); } else if (event is XmppSocketClosureEvent) { - if (_socketClosureTriggersReconnect) { - _log.fine('Received XmppSocketClosureEvent. Reconnecting...'); - await _reconnectionPolicy.onFailure(); + if (!event.expected) { + _log.fine('Received unexpected XmppSocketClosureEvent. Reconnecting...'); + await handleError(SocketError(XmppSocketErrorEvent(event))); } else { _log.fine('Received XmppSocketClosureEvent. No reconnection attempt since _socketClosureTriggersReconnect is false...'); } @@ -850,6 +846,7 @@ class XmppConnection { final result = await _currentNegotiator!.negotiate(nonza); if (result.isType()) { _log.severe('Negotiator returned an error'); + await _resetIsConnectionRunning(); await handleError(result.get()); return; } @@ -873,6 +870,8 @@ class XmppConnection { if (_isMandatoryNegotiationDone(_streamFeatures) && !_isNegotiationPossible(_streamFeatures)) { _log.finest('Negotiations done!'); _updateRoutingState(RoutingState.handleStanzas); + await _reconnectionPolicy.onSuccess(); + await _resetIsConnectionRunning(); await _onNegotiationsDone(); } else { _currentNegotiator = getNextNegotiator(_streamFeatures); @@ -896,6 +895,8 @@ class XmppConnection { _log.finest('Negotiations done!'); _updateRoutingState(RoutingState.handleStanzas); + await _reconnectionPolicy.onSuccess(); + await _resetIsConnectionRunning(); await _onNegotiationsDone(); } else { _log.finest('Picking new negotiator...'); @@ -912,6 +913,8 @@ class XmppConnection { _log.finest('Negotiator wants to skip the remaining negotiation... Negotiations (assumed) done!'); _updateRoutingState(RoutingState.handleStanzas); + await _reconnectionPolicy.onSuccess(); + await _resetIsConnectionRunning(); await _onNegotiationsDone(); break; } @@ -1023,7 +1026,6 @@ class XmppConnection { Future _disconnect({required XmppConnectionState state, bool triggeredByUser = true}) async { _reconnectionPolicy.setShouldReconnect(false); - _socketClosureTriggersReconnect = false; if (triggeredByUser) { getPresenceManager().sendUnavailablePresence(); @@ -1079,7 +1081,6 @@ class XmppConnection { } await _reconnectionPolicy.reset(); - _socketClosureTriggersReconnect = true; await _sendEvent(ConnectingEvent()); final smManager = getStreamManagementManager(); diff --git a/packages/moxxmpp/lib/src/socket.dart b/packages/moxxmpp/lib/src/socket.dart index 0de7f34..f7dcd7a 100644 --- a/packages/moxxmpp/lib/src/socket.dart +++ b/packages/moxxmpp/lib/src/socket.dart @@ -5,13 +5,17 @@ abstract class XmppSocketEvent {} /// Triggered by the socket when an error occurs. class XmppSocketErrorEvent extends XmppSocketEvent { - XmppSocketErrorEvent(this.error); final Object error; } /// 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. abstract class BaseSocketWrapper {