public static async ValueTask <RemoteJSDataStream> CreateRemoteJSDataStreamAsync(
        RemoteJSRuntime runtime,
        IJSStreamReference jsStreamReference,
        long totalLength,
        long signalRMaximumIncomingBytes,
        TimeSpan jsInteropDefaultCallTimeout,
        CancellationToken cancellationToken = default)
    {
        // Enforce minimum 1 kb, maximum 50 kb, SignalR message size.
        // We budget 512 bytes overhead for the transfer, thus leaving at least 512 bytes for data
        // transfer per chunk with a 1 kb message size.
        // Additionally, to maintain interactivity, we put an upper limit of 50 kb on the message size.
        var chunkSize = signalRMaximumIncomingBytes > 1024 ?
                        (int)Math.Min(signalRMaximumIncomingBytes, 50 * 1024) - 512 :
                        throw new ArgumentException($"SignalR MaximumIncomingBytes must be at least 1 kb.");

        var streamId           = runtime.RemoteJSDataStreamNextInstanceId++;
        var remoteJSDataStream = new RemoteJSDataStream(runtime, streamId, totalLength, chunkSize, jsInteropDefaultCallTimeout, cancellationToken);
        await runtime.InvokeVoidAsync("Blazor._internal.sendJSDataStream", jsStreamReference, streamId, chunkSize);

        return(remoteJSDataStream);
    }
Beispiel #2
0
    // ReceiveJSDataChunk is used in a fire-and-forget context, so it's responsible for its own
    // error handling.
    internal async Task <bool> ReceiveJSDataChunk(long streamId, long chunkId, byte[] chunk, string error)
    {
        AssertInitialized();
        AssertNotDisposed();

        try
        {
            return(await Renderer.Dispatcher.InvokeAsync(() =>
            {
                return RemoteJSDataStream.ReceiveData(JSRuntime, streamId, chunkId, chunk, error);
            }));
        }
        catch (Exception ex)
        {
            // An error completing JS interop means that the user sent invalid data, a well-behaved
            // client won't do this.
            Log.ReceiveJSDataChunkException(_logger, streamId, ex);
            await TryNotifyClientErrorAsync(Client, GetClientErrorMessage(ex, "Invalid chunk supplied to stream."));

            UnhandledException?.Invoke(this, new UnhandledExceptionEventArgs(ex, isTerminating: false));
            return(false);
        }
    }