start method

Future<void> start({
  1. void onDone()?,
  2. void onError(
    1. Object? error
    )?,
})

Implementation

Future<void> start({void Function()? onDone, void Function(Object? error)? onError}) async {
  if (_entered) {
    throw RoomServerException('room client already started');
  }
  _doneHandler = onDone;
  _errorHandler = onError;
  try {
    try {
      await _openProtocol(initial: true);
    } on _ProtocolStartupFailure catch (error) {
      if (!_isRetryableStartupClose(kind: error.kind, reason: error.reason) || _reconnectTimeout == Duration.zero) {
        _setStartupTerminalState(closeKind: error.kind, closeReason: error.reason, protocol: _protocolInstance);
        throw _startupException(closeKind: error.kind, closeReason: error.reason, protocol: _protocolInstance);
      }

      await _closeProtocol(_protocolInstance);
      final retryResult = await _retryProtocolConnection(
        disconnectReason: error.reason,
        protocolFactoryFailureLogMessage: 'unable to create replacement room protocol during initial startup',
        attemptFailureLogMessage: 'room startup attempt failed',
        attempt: _attemptInitialProtocolStartup,
      );
      if (!retryResult.connected) {
        _finalizeInitialStartupRetryFailure(retryResult: retryResult);
      }
    } catch (error, stackTrace) {
      final nonRetryableCloseReason = _nonRetryableConnectFailureReason(error);
      if (nonRetryableCloseReason != null) {
        _finalizeInitialStartupRetryFailure(
          retryResult: _ProtocolRetryResult(connected: false, closeKind: ProtocolCloseKind.error, closeReason: nonRetryableCloseReason),
        );
      }

      final closeKind = _protocolInstance.closeKind;
      if (closeKind != null && !_isRetryableStartupClose(kind: closeKind, reason: _protocolInstance.closeReason)) {
        _setStartupTerminalState(closeKind: closeKind, closeReason: _protocolInstance.closeReason, protocol: _protocolInstance);
        throw _startupException(closeKind: closeKind, closeReason: _protocolInstance.closeReason, protocol: _protocolInstance);
      }

      final closeReason = _connectionFailureReason(error);
      if (_reconnectTimeout == Duration.zero) {
        _setStartupTerminalState(closeKind: ProtocolCloseKind.error, closeReason: closeReason, protocol: _protocolInstance);
        throw _startupException(closeKind: ProtocolCloseKind.error, closeReason: closeReason, protocol: _protocolInstance);
      }

      _roomClientLogger.log(Level.FINE, 'room startup attempt failed', error, stackTrace);
      await _closeProtocol(_protocolInstance);
      final retryResult = await _retryProtocolConnection(
        disconnectReason: closeReason,
        protocolFactoryFailureLogMessage: 'unable to create replacement room protocol during initial startup',
        attemptFailureLogMessage: 'room startup attempt failed',
        attempt: _attemptInitialProtocolStartup,
      );
      if (!retryResult.connected) {
        _finalizeInitialStartupRetryFailure(retryResult: retryResult);
      }
    }
    sync.start();
    messaging.start();
    _entered = true;
    _markConnected();
    messaging._onRoomReconnect();
    _lifecycleTask = _connectionLifecycle();
  } catch (error) {
    sync.dispose();
    unawaited(messaging.stop());
    _protocolInstance.dispose();
    rethrow;
  }

  await ready;
}