1 #region Copyright notice and license 2 3 // Copyright 2015-2016 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #endregion 18 19 using System; 20 using System.Collections.Generic; 21 using System.Threading; 22 using System.Threading.Tasks; 23 using Grpc.Core; 24 using Grpc.Core.Utils; 25 26 namespace Math 27 { 28 /// <summary> 29 /// Implementation of MathService server 30 /// </summary> 31 public class MathServiceImpl : Math.MathBase 32 { Div(DivArgs request, ServerCallContext context)33 public override Task<DivReply> Div(DivArgs request, ServerCallContext context) 34 { 35 return Task.FromResult(DivInternal(request)); 36 } 37 Fib(FibArgs request, IServerStreamWriter<Num> responseStream, ServerCallContext context)38 public override async Task Fib(FibArgs request, IServerStreamWriter<Num> responseStream, ServerCallContext context) 39 { 40 var limit = request.Limit > 0 ? request.Limit : long.MaxValue; 41 var fibEnumerator = FibInternal(limit).GetEnumerator(); 42 43 // Keep streaming the sequence until the call is cancelled. 44 // Use CancellationToken from ServerCallContext to detect the cancellation. 45 while (!context.CancellationToken.IsCancellationRequested && fibEnumerator.MoveNext()) 46 { 47 await responseStream.WriteAsync(fibEnumerator.Current); 48 await Task.Delay(100); 49 } 50 } 51 Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context)52 public override async Task<Num> Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context) 53 { 54 long sum = 0; 55 await requestStream.ForEachAsync(num => 56 { 57 sum += num.Num_; 58 return TaskUtils.CompletedTask; 59 }); 60 return new Num { Num_ = sum }; 61 } 62 DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)63 public override async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context) 64 { 65 await requestStream.ForEachAsync(async divArgs => await responseStream.WriteAsync(DivInternal(divArgs))); 66 } 67 DivInternal(DivArgs args)68 static DivReply DivInternal(DivArgs args) 69 { 70 if (args.Divisor == 0) 71 { 72 // One can finish the RPC with non-ok status by throwing RpcException instance. 73 // Alternatively, resulting status can be set using ServerCallContext.Status 74 throw new RpcException(new Status(StatusCode.InvalidArgument, "Division by zero")); 75 } 76 77 long quotient = args.Dividend / args.Divisor; 78 long remainder = args.Dividend % args.Divisor; 79 return new DivReply { Quotient = quotient, Remainder = remainder }; 80 } 81 FibInternal(long n)82 static IEnumerable<Num> FibInternal(long n) 83 { 84 long a = 1; 85 yield return new Num { Num_ = a }; 86 87 long b = 1; 88 for (long i = 0; i < n - 1; i++) 89 { 90 long temp = a; 91 a = b; 92 b = temp + b; 93 yield return new Num { Num_ = a }; 94 } 95 } 96 } 97 } 98