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)); }
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); }
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); }
/// <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, }); }
/// <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)); }
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); }
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); } } }
public static Stream AsStream(this PipeReader pipeReader) => pipeReader.AsStream(leaveOpen: false);
public ValueTask <object> Deserialize(PipeReader reader, Type type, CancellationToken cancellationToken) { var model = Serializer.Deserialize(type, reader.AsStream()); return(new ValueTask <object>(model)); }