Initial Client/Server Communication
#1 Followed the MagicOnion quickstart guide, borrowing code from the chat sample app to get something working
This commit is contained in:
parent
52b0d4d8ff
commit
a0c8dbee72
493 changed files with 57790 additions and 3 deletions
137
Assets/Scripts/MessagePack/StreamPolyfillExtensions.cs
Normal file
137
Assets/Scripts/MessagePack/StreamPolyfillExtensions.cs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
// Copyright (c) All contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft;
|
||||
|
||||
namespace MessagePack
|
||||
{
|
||||
#if !SPAN_BUILTIN
|
||||
internal static class StreamPolyfillExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads from the stream into a memory buffer.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to read from.</param>
|
||||
/// <param name="buffer">The buffer to read directly into.</param>
|
||||
/// <returns>The number of bytes actually read.</returns>
|
||||
internal static int Read(this Stream stream, Span<byte> buffer)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
}
|
||||
|
||||
byte[] array = ArrayPool<byte>.Shared.Rent(buffer.Length);
|
||||
try
|
||||
{
|
||||
int bytesRead = stream.Read(array, 0, buffer.Length);
|
||||
new Span<byte>(array, 0, bytesRead).CopyTo(buffer);
|
||||
return bytesRead;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(array);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads from the stream into a memory buffer.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to read from.</param>
|
||||
/// <param name="buffer">The buffer to read directly into.</param>
|
||||
/// <param name="cancellationToken">A cancellation token.</param>
|
||||
/// <returns>The number of bytes actually read.</returns>
|
||||
/// <devremarks>
|
||||
/// This method shamelessly copied from the .NET Core 2.1 Stream class: https://github.com/dotnet/coreclr/blob/a113b1c803783c9d64f1f0e946ff9a853e3bc140/src/System.Private.CoreLib/shared/System/IO/Stream.cs#L366-L391.
|
||||
/// </devremarks>
|
||||
internal static ValueTask<int> ReadAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
}
|
||||
|
||||
if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> array))
|
||||
{
|
||||
return new ValueTask<int>(stream.ReadAsync(array.Array, array.Offset, array.Count, cancellationToken));
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
|
||||
return FinishReadAsync(stream.ReadAsync(sharedBuffer, 0, buffer.Length, cancellationToken), sharedBuffer, buffer);
|
||||
|
||||
async ValueTask<int> FinishReadAsync(Task<int> readTask, byte[] localBuffer, Memory<byte> localDestination)
|
||||
{
|
||||
try
|
||||
{
|
||||
int result = await readTask.ConfigureAwait(false);
|
||||
new Span<byte>(localBuffer, 0, result).CopyTo(localDestination.Span);
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(localBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a span to the stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to write to.</param>
|
||||
/// <param name="buffer">The buffer to write.</param>
|
||||
internal static void Write(this Stream stream, ReadOnlySpan<byte> buffer)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
}
|
||||
|
||||
var sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
|
||||
try
|
||||
{
|
||||
buffer.CopyTo(sharedBuffer);
|
||||
stream.Write(sharedBuffer, 0, buffer.Length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(sharedBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a span to the stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to write to.</param>
|
||||
/// <param name="buffer">The buffer to write.</param>
|
||||
/// <param name="cancellationToken">A cancellation token.</param>
|
||||
internal static async ValueTask WriteAsync(this Stream stream, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
}
|
||||
|
||||
var sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
|
||||
try
|
||||
{
|
||||
buffer.CopyTo(sharedBuffer);
|
||||
await stream.WriteAsync(sharedBuffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(sharedBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Loading…
Reference in a new issue