startProgressiveCall method

ProgressiveCall startProgressiveCall(
  1. String procedure, {
  2. List? arguments,
  3. Map<String, dynamic>? argumentsKeywords,
  4. CallOptions? options,
  5. Completer<String>? cancelCompleter,
  6. bool enableFileSegments = false,
})

Implementation

ProgressiveCall startProgressiveCall(
  String procedure, {
  List<dynamic>? arguments,
  Map<String, dynamic>? argumentsKeywords,
  CallOptions? options,
  Completer<String>? cancelCompleter,
  bool enableFileSegments = false,
}) {
  final initiatingOptions = CallOptions(
    progress: true,
    receiveProgress: options?.receiveProgress,
    timeout: options?.timeout,
    discloseMe: options?.discloseMe,
    pptScheme: options?.pptScheme,
    pptSerializer: options?.pptSerializer,
    pptCipher: options?.pptCipher,
    pptKeyId: options?.pptKeyId,
    custom: options?.custom,
  );
  final call = _buildCallLazyPayload(
    procedure,
    payload: LazyMessagePayload.materialized(
      arguments: arguments,
      argumentsKeywords: argumentsKeywords,
    ),
    options: initiatingOptions,
  );
  final controller = StreamController<Result>(
    sync: true,
    onCancel: () async {
      final pending = _pendingCalls.remove(call.requestId);
      if (pending != null) {
        await pending.close();
      }
    },
  );
  _pendingCalls[call.requestId] = _PendingCallStream(
    procedure: procedure,
    controller: controller,
  );
  _transport.send(call);
  _attachCallCancellation(call.requestId, cancelCompleter);

  final availableFileTransport =
      enableFileSegments &&
          _transport is FileSegmentTransport &&
          (_transport as FileSegmentTransport).supportsFileSegments
      ? _transport as FileSegmentTransport
      : null;
  final fileTransport = initiatingOptions.pptScheme == null
      ? availableFileTransport
      : null;
  final outboundE2eeProvider = call.e2eeProvider;
  final nativeE2eeCandidate = outboundE2eeProvider as Object?;
  NativeE2eeFileSegmentProvider? nativeE2eeProvider;
  if (initiatingOptions.pptScheme == ConnectanumE2eeProfile.scheme &&
      nativeE2eeCandidate is NativeE2eeFileSegmentProvider &&
      nativeE2eeCandidate.supportsNativeE2eeFileSegments) {
    nativeE2eeProvider = nativeE2eeCandidate;
  }
  NativeE2eeFileSegmentTransport? nativeE2eeFileTransport;
  if (nativeE2eeProvider != null &&
      availableFileTransport is NativeE2eeFileSegmentTransport &&
      availableFileTransport.supportsNativeE2eeFileSegments) {
    nativeE2eeFileTransport = availableFileTransport;
  }
  final sourceTransport = fileTransport ?? nativeE2eeFileTransport;

  Call buildChunk(LazyMessagePayload payload, bool progress) {
    if (!_pendingCalls.containsKey(call.requestId)) {
      throw StateError('The progressive call is no longer active');
    }
    final chunk = Call(
      call.requestId,
      procedure,
      options: CallOptions(progress: progress),
    );
    chunk.attachE2eeRuntimeContext(
      _buildOutboundRuntimeContext(
        messageType: WampE2eeMessageType.call,
        uri: procedure,
      ),
    );
    _applyOutboundLazyPayload(chunk, payload, initiatingOptions);
    return chunk;
  }

  return ProgressiveCall._(
    requestId: call.requestId,
    results: controller.stream,
    send: (payload, progress) {
      _transport.send(buildChunk(payload, progress));
    },
    drain: _transport is DrainableTransport
        ? (_transport as DrainableTransport).drain
        : null,
    openFileSource: sourceTransport?.openFileSegmentSource,
    sendFileSegment: sourceTransport == null
        ? null
        : (source, offset, length, progress) {
            if (nativeE2eeFileTransport != null &&
                nativeE2eeProvider != null) {
              final options = CallOptions(
                progress: progress,
                pptScheme: initiatingOptions.pptScheme,
                pptSerializer: initiatingOptions.pptSerializer,
                pptCipher: initiatingOptions.pptCipher,
                pptKeyId: initiatingOptions.pptKeyId,
              );
              final chunk = Call(
                call.requestId,
                procedure,
                options: options,
                arguments: <dynamic>[Uint8List(0)],
              );
              final runtimeContext = _buildOutboundRuntimeContext(
                messageType: WampE2eeMessageType.call,
                uri: procedure,
              );
              chunk.attachE2eeProvider(outboundE2eeProvider);
              chunk.attachE2eeRuntimeContext(runtimeContext);
              final e2ee = nativeE2eeProvider.prepareNativeE2eeFileSegment(
                options,
                runtimeContext: runtimeContext,
              );
              nativeE2eeFileTransport.sendNativeE2eeFileSegment(
                chunk,
                source: source,
                offset: offset,
                length: length,
                e2ee: e2ee,
              );
              return;
            }
            final chunk = buildChunk(
              LazyMessagePayload.materialized(
                arguments: <dynamic>[Uint8List(0)],
              ),
              progress,
            );
            fileTransport!.sendFileSegment(
              chunk,
              source: source,
              offset: offset,
              length: length,
            );
          },
  );
}