async Task <TResponse> AsyncCallAsync <TRequest, TResponse>( Method <TRequest, TResponse> method, TRequest request) { await pipeLock.WaitAsync(); PipePair pipePair; availablePipePairs.TryTake(out pipePair); Debug.Assert(pipePair != null); try { var writer = new AsyncBinaryWriter(pipePair.OutPipe); var reader = new AsyncBinaryReader(pipePair.InPipe); // Send the RPC name. await writer.WriteAsync(method.FullName.Length); await writer.WriteAsync(Encoding.ASCII.GetBytes(method.FullName)); // Send the request. using (var serializationContext = new SimpleSerializationContext()) { method.RequestMarshaller.ContextualSerializer(request, serializationContext); byte[] requestBytes = serializationContext.GetPayload(); await writer.WriteAsync(requestBytes.Length); await writer.WriteAsync(requestBytes); } // Read the response. int size = await reader.ReadInt32Async(); byte[] responseBytes = await reader.ReadBytesAsync(size); var deserializationContext = new SimpleDeserializationContext(responseBytes); return(method.ResponseMarshaller.ContextualDeserializer(deserializationContext)); } // Unfortunately, RpcExceptions can't be nested with InnerException. catch (EndOfStreamException e) { throw new RpcException(new Status(StatusCode.Unknown, e.ToString()), "Connection to server lost. Did it shut down?"); } catch (Exception e) when(!(e is RpcException)) { throw new RpcException(new Status(StatusCode.Unknown, e.ToString()), "Unknown failure: " + e); } finally { availablePipePairs.Add(pipePair); pipeLock.Release(); } }
public override TResponse BlockingUnaryCall <TRequest, TResponse>( Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request) { // Wait for an available pipe. pipeLock.Wait(); PipePair pipePair; availablePipePairs.TryTake(out pipePair); Debug.Assert(pipePair != null); try { // Create binary reader/writer, but be sure to leave the stream open! var writer = new BinaryWriter(pipePair.OutPipe, Encoding.Default, true); var reader = new BinaryReader(pipePair.InPipe, Encoding.Default, true); // Send the RPC name. writer.Write(method.FullName.Length); writer.Write(Encoding.ASCII.GetBytes(method.FullName)); // Send the request. using (var serializationContext = new SimpleSerializationContext()) { method.RequestMarshaller.ContextualSerializer(request, serializationContext); byte[] requestBytes = serializationContext.GetPayload(); writer.Write(requestBytes.Length); writer.Write(requestBytes); } // Read the response. int size = reader.ReadInt32(); byte[] responseBytes = reader.ReadBytes(size); var deserializationContext = new SimpleDeserializationContext(responseBytes); return(method.ResponseMarshaller.ContextualDeserializer(deserializationContext)); } // Unfortunately, RpcExceptions can't be nested with InnerException. catch (EndOfStreamException e) { throw new RpcException(new Status(StatusCode.Unknown, e.ToString()), "Connection to server lost. Did it shut down?"); } catch (Exception e) when(!(e is RpcException)) { throw new RpcException(new Status(StatusCode.Unknown, e.ToString()), "Unknown failure: " + e); } finally { availablePipePairs.Add(pipePair); pipeLock.Release(); } }
public override void AddMethod <TRequest, TResponse>(Method <TRequest, TResponse> method, UnaryServerMethod <TRequest, TResponse> handler) { IProcessMessage processor = new MethodAndHandler <TRequest, TResponse>( requestBytes => { var context = new SimpleDeserializationContext(requestBytes); return(method.RequestMarshaller.ContextualDeserializer(context)); }, request => { using (var context = new SimpleSerializationContext()) { method.ResponseMarshaller.ContextualSerializer(request, context); return(context.GetPayload()); } }, handler); messageProcessors.Add(method.FullName, processor); }