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
132
Assets/Scripts/MagicOnion.Abstractions/ClientStreamingResult.cs
Normal file
132
Assets/Scripts/MagicOnion.Abstractions/ClientStreamingResult.cs
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
using Grpc.Core;
|
||||
using MessagePack;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MagicOnion
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapped AsyncClientStreamingCall.
|
||||
/// </summary>
|
||||
public struct ClientStreamingResult<TRequest, TResponse> : IDisposable
|
||||
{
|
||||
internal readonly TResponse rawValue;
|
||||
internal readonly bool hasRawValue;
|
||||
readonly AsyncClientStreamingCall<byte[], byte[]> inner;
|
||||
readonly IClientStreamWriter<TRequest> requestStream;
|
||||
readonly MessagePackSerializerOptions serializerOptions;
|
||||
|
||||
public ClientStreamingResult(TResponse rawValue)
|
||||
{
|
||||
this.hasRawValue = true;
|
||||
this.rawValue = rawValue;
|
||||
this.inner = null;
|
||||
this.requestStream = null;
|
||||
this.serializerOptions = null;
|
||||
}
|
||||
|
||||
public ClientStreamingResult(AsyncClientStreamingCall<byte[], byte[]> inner, IClientStreamWriter<TRequest> requestStream, MessagePackSerializerOptions serializerOptions)
|
||||
{
|
||||
this.hasRawValue = false;
|
||||
this.rawValue = default(TResponse);
|
||||
this.inner = inner;
|
||||
this.requestStream = requestStream;
|
||||
this.serializerOptions = serializerOptions;
|
||||
}
|
||||
|
||||
async Task<TResponse> Deserialize()
|
||||
{
|
||||
var bytes = await inner.ResponseAsync.ConfigureAwait(false);
|
||||
return MessagePackSerializer.Deserialize<TResponse>(bytes, serializerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronous call result.
|
||||
/// </summary>
|
||||
public Task<TResponse> ResponseAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
if (hasRawValue)
|
||||
{
|
||||
return Task.FromResult(rawValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Deserialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronous access to response headers.
|
||||
/// </summary>
|
||||
public Task<Metadata> ResponseHeadersAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.inner.ResponseHeadersAsync;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Async stream to send streaming requests.
|
||||
/// </summary>
|
||||
public IClientStreamWriter<TRequest> RequestStream
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.requestStream;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows awaiting this object directly.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TaskAwaiter<TResponse> GetAwaiter()
|
||||
{
|
||||
return ResponseAsync.GetAwaiter();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the call status if the call has already finished.
|
||||
/// Throws InvalidOperationException otherwise.
|
||||
/// </summary>
|
||||
public Status GetStatus()
|
||||
{
|
||||
return this.inner.GetStatus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the call trailing metadata if the call has already finished.
|
||||
/// Throws InvalidOperationException otherwise.
|
||||
/// </summary>
|
||||
public Metadata GetTrailers()
|
||||
{
|
||||
return this.inner.GetTrailers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides means to cleanup after the call.
|
||||
/// If the call has already finished normally (request stream has been completed and call result has been received), doesn't do anything.
|
||||
/// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
|
||||
/// As a result, all resources being used by the call should be released eventually.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Normally, there is no need for you to dispose the call unless you want to utilize the
|
||||
/// "Cancel" semantics of invoking <c>Dispose</c>.
|
||||
/// </remarks>
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.inner != null)
|
||||
{
|
||||
this.inner.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue