handleXmlStream method

Future<void> handleXmlStream(
  1. XMPPStreamObject event
)

Called whenever we receive data that has been parsed as XML.

Implementation

Future<void> handleXmlStream(XMPPStreamObject event) async {
  if (event is XMPPStreamHeader) {
    await _negotiationsHandler.negotiate(event);
    return;
  }

  assert(
    event is XMPPStreamElement,
    'The event must be a XMPPStreamElement',
  );
  final node = (event as XMPPStreamElement).node;

  // Check if we received a stream error
  if (node.tag == 'stream:error') {
    _log
      ..finest('<== ${node.toXml()}')
      ..severe('Received a stream error! Attempting reconnection');
    await handleError(StreamError());

    return;
  }

  switch (_routingState) {
    case RoutingState.negotiating:
      _log.finest('<== ${node.toXml()}');

      // Why lock here? The problem is that if we do stream resumption, then we might
      // receive "<resumed .../><iq .../>...", which will all be fed into the negotiator,
      // causing (a) the negotiator to become confused and (b) the stanzas/nonzas to be
      // missed. This causes the data to wait while the negotiator is running and thus
      // prevent this issue.
      if (_routingState != RoutingState.negotiating) {
        unawaited(handleXmlStream(event));
        return;
      }

      await _negotiationsHandler.negotiate(event);
      break;
    case RoutingState.handleStanzas:
      await _handleStanza(node);
      break;
    case RoutingState.preConnection:
    case RoutingState.error:
      _log.warning('Received data while in non-receiving state');
      break;
  }
}