connect<T extends VmService> function

Future<T> connect<T extends VmService>({
  1. required Uri uri,
  2. required Completer<void> finishedCompleter,
  3. required VmServiceFactory<T> serviceFactory,
})

Implementation

Future<T> connect<T extends VmService>({
  required Uri uri,
  required Completer<void> finishedCompleter,
  required VmServiceFactory<T> serviceFactory,
}) {
  final connectedCompleter = Completer<T>();

  void onError(Object? error) {
    if (!connectedCompleter.isCompleted) {
      connectedCompleter.completeError(error!);
    }
  }

  // Connects to a VM Service but does not verify the connection was fully
  // successful.
  Future<T> connectHelper() async {
    final useSse = uri.scheme == 'sse' || uri.scheme == 'sses';
    final T service = useSse
        ? await _connectWithSse<T>(
            uri: uri,
            onError: onError,
            finishedCompleter: finishedCompleter,
            serviceFactory: serviceFactory,
          )
        : await _connectWithWebSocket<T>(
            uri: uri,
            onError: onError,
            finishedCompleter: finishedCompleter,
            serviceFactory: serviceFactory,
          );
    // Verify that the VM is alive enough to actually get the version before
    // considering it successfully connected. Otherwise, VMService instances
    // that failed part way through the connection may appear to be connected.
    await service.getVersion();
    return service;
  }

  connectHelper().then(
    (service) {
      if (!connectedCompleter.isCompleted) {
        connectedCompleter.complete(service);
      }
    },
    onError: onError,
  );
  finishedCompleter.future.then((_) {
    // It is an error if we finish before we are connected.
    if (!connectedCompleter.isCompleted) {
      onError(null);
    }
  });
  return connectedCompleter.future;
}