示例#1
0
        public ValueTask <object> Deserialize(PipeReader reader, Type type, CancellationToken cancellationToken)
        {
            XmlSerializer serializer = this.GetSerializer(type);
            var           model      = serializer.Deserialize(reader.AsStream());

            return(new ValueTask <object>(model));
        }
示例#2
0
        public async Task <byte[]> ReadRequestMessageAsync(
            PipeReader bodyReader,
            IList <string> orderedParameterNames,
            IMethod method,
            CancellationToken token)
        {
            var values         = new object?[orderedParameterNames.Count];
            var methodAccessor = CreateMethodAccessor(method);

            if (orderedParameterNames.Count > 0)
            {
                var requestParameterTypes = methodAccessor.GetParameterTypes();

                JsonElement body;
                using (var stream = bodyReader.AsStream())
                {
                    var options = new JsonSerializerOptions {
                        PropertyNameCaseInsensitive = true
                    };
                    body = await JsonSerializer.DeserializeAsync <JsonElement>(stream, options, token).ConfigureAwait(false);
                }

                foreach (var entry in body.EnumerateObject())
                {
                    var index = FindIndex(orderedParameterNames, entry.Name);
                    if (index < 0)
                    {
                        continue;
                    }

                    var parameterType = requestParameterTypes[index];
                    try
                    {
                        values[index] = _serializer.Deserialize(entry.Value.GetRawText(), parameterType);
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException(
                                  "Fail to deserialize parameter [{0}] with type [{1}] from request.".FormatWith(entry.Name, parameterType),
                                  ex);
                    }
                }
            }

            var payload = methodAccessor.SerializeRequest(values);

            var result = new byte[payload.Length + 5];

            // not compressed
            result[0] = 0;

            // length
            BinaryPrimitives.WriteUInt32BigEndian(result.AsSpan(1), (uint)payload.Length);

            // data
            Buffer.BlockCopy(payload, 0, result, 5, payload.Length);

            return(result);
        }
示例#3
0
        public async Task <long> AcceptPipeReader(string fileName, PipeReader reader, CancellationToken cancellationToken)
        {
            Assert.Equal(ExpectedFileName, fileName);
            var ms = new MemoryStream();

            using (Stream contentStream = reader.AsStream())
            {
                await contentStream.CopyToAsync(ms, 4096, cancellationToken);

                Assert.Equal <byte>(MemoryBuffer, ms.ToArray());
            }

            return(ms.Length);
        }
示例#4
0
    /// <summary>
    /// Writes the contents of specified <see cref="System.IO.Pipelines.PipeReader"/> to the response.
    /// <para>
    /// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
    /// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
    /// </para>
    /// </summary>
    /// <param name="pipeReader">The <see cref="System.IO.Pipelines.PipeReader"/> to write to the response.</param>
    /// <param name="contentType">The <c>Content-Type</c> of the response. Defaults to <c>application/octet-stream</c>.</param>
    /// <param name="fileDownloadName">The the file name to be used in the <c>Content-Disposition</c> header.</param>
    /// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified.
    /// Used to configure the <c>Last-Modified</c> response header and perform conditional range requests.</param>
    /// <param name="entityTag">The <see cref="EntityTagHeaderValue"/> to be configure the <c>ETag</c> response header
    /// and perform conditional requests.</param>
    /// <param name="enableRangeProcessing">Set to <c>true</c> to enable range requests processing.</param>
    /// <returns>The created <see cref="IResult"/> for the response.</returns>
    /// <remarks>
    /// The <paramref name="pipeReader" /> parameter is completed after the response is sent.
    /// </remarks>
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
    public static IResult Stream(
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
        PipeReader pipeReader,
        string?contentType             = null,
        string?fileDownloadName        = null,
        DateTimeOffset?lastModified    = null,
        EntityTagHeaderValue?entityTag = null,
        bool enableRangeProcessing     = false)
    {
        return(new FileStreamResult(pipeReader.AsStream(), contentType)
        {
            LastModified = lastModified,
            EntityTag = entityTag,
            FileDownloadName = fileDownloadName,
            EnableRangeProcessing = enableRangeProcessing,
        });
    }
示例#5
0
        /// <summary>
        /// Deserializes the content from <paramref name="reader"/> as <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">The type to deserialize as.</typeparam>
        /// <param name="serializer">The serializer to use.</param>
        /// <param name="reader">The content to deserialize.</param>
        /// <param name="cancellationToken">Used to signal cancellation to running operations.</param>
        /// <returns>
        /// A <see cref="Task{TResult}"/> representing the asynchronous operation containing the deserialized value.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Thrown when <paramref name="serializer"/> or <paramref name="reader"/> are null.
        /// </exception>
        public static Task <T> DeserializeAsync <T>(
            this ISerializer serializer,
            PipeReader reader,
            CancellationToken cancellationToken = default)
        {
            if (serializer == null)
            {
                throw new ArgumentNullException(nameof(serializer));
            }
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            using var stream = reader.AsStream();
            return(serializer.DeserializeAsync <T>(stream, cancellationToken));
        }
示例#6
0
        internal static ulong Decode(PipeReader reader)
        {
            ulong result = 0;
            int   current;
            int   shift = 0;

            do
            {
                current = reader.AsStream().ReadByte();
                if (current == -1)
                {
                    throw new InvalidDataException("Expected another byte for varint");
                }

                var add = (ulong)(((byte)((current) & rest)) << shift);
                result += add;
                shift  += 7;
            } while ((current & mostSignificantBit) == 128);

            return(result);
        }
示例#7
0
        static async Task Main(string[] args)
        {
            using var cts = new CancellationTokenSource();

            Console.CancelKeyPress += (s, e) =>
            {
                if (!cts.IsCancellationRequested)
                {
                    Console.Error.WriteLine("Cancellation requested. CTRL+C again to force close.");
                    cts.Cancel();
                    e.Cancel = true;
                }
            };

            var pipeOptions  = new PipeOptions(pauseWriterThreshold: 256, resumeWriterThreshold: 64, useSynchronizationContext: false);
            var clientBuffer = new Pipe(pipeOptions);
            var serverBuffer = new Pipe(pipeOptions);

            PipeReader clientReader = clientBuffer.Reader;
            PipeWriter clientWriter = new ThrottledPipeWriter(serverBuffer.Writer, ClientBandwidthInBytes, PingInMilliseconds);

            PipeReader serverReader = serverBuffer.Reader;
            PipeWriter serverWriter = new ThrottledPipeWriter(clientBuffer.Writer, ServerBandwidthInBytes, PingInMilliseconds);

            await Task.WhenAll(RunClientSenderAsync(), RunClientReceiverAsync(), RunServerAsync()).ConfigureAwait(false);

            async Task RunClientSenderAsync()
            {
                long request = 0;

                try
                {
                    await using var sw = new StreamWriter(clientWriter.AsStream());

                    while (!cts.IsCancellationRequested)
                    {
                        await sw.WriteLineAsync($"[{++request}] sent {Environment.TickCount64}").ConfigureAwait(false);

                        await sw.FlushAsync().ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    await Console.Error.WriteLineAsync($"client sender error: {ex}").ConfigureAwait(false);
                }
                finally
                {
                    await Console.Error.WriteLineAsync($"client sender shutdown. last request: {request}").ConfigureAwait(false);
                }
            }

            async Task RunClientReceiverAsync()
            {
                try
                {
                    using var sr = new StreamReader(clientReader.AsStream());

                    while (await sr.ReadLineAsync().ConfigureAwait(false) is string line)
                    {
                        long  ticks      = Environment.TickCount64;
                        Match m          = Regex.Match(line, @"\[\d+\]\s+sent\s+(\d+),\s+reply\s+sent\s+\d+");
                        long  firstTicks = long.Parse(m.Groups[1].Value);

                        await Console.Out.WriteLineAsync($"{line}, reply received {ticks} (total latency {ticks - firstTicks:N0})").ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    await Console.Error.WriteLineAsync($"client receiver error: {ex}").ConfigureAwait(false);
                }
                finally
                {
                    await Console.Error.WriteLineAsync("client receiver shutdown").ConfigureAwait(false);
                }
            }

            async Task RunServerAsync()
            {
                try
                {
                    using var sr       = new StreamReader(serverReader.AsStream());
                    await using var sw = new StreamWriter(serverWriter.AsStream());

                    while (await sr.ReadLineAsync().ConfigureAwait(false) is string line)
                    {
                        await sw.WriteLineAsync($"{line}, reply sent {Environment.TickCount64}").ConfigureAwait(false);

                        await sw.FlushAsync().ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    await Console.Error.WriteLineAsync($"server error: {ex}").ConfigureAwait(false);
                }
                finally
                {
                    await Console.Error.WriteLineAsync("server shutdown").ConfigureAwait(false);
                }
            }
        }
示例#8
0
 public static Stream AsStream(this PipeReader pipeReader) => pipeReader.AsStream(leaveOpen: false);
示例#9
0
        public ValueTask <object> Deserialize(PipeReader reader, Type type, CancellationToken cancellationToken)
        {
            var model = Serializer.Deserialize(type, reader.AsStream());

            return(new ValueTask <object>(model));
        }