static async Task Main()
    {
        Console.Title = "Sender";

        #region route-message-to-original-destination

        var config    = new EndpointConfiguration("Sender");
        var transport = config.UseTransport <LearningTransport>();
        var routing   = transport.Routing();

        routing.RouteToEndpoint(typeof(ImportantMessage), "OriginalDestination");

        #endregion

        var endpoint = await Endpoint.Start(config)
                       .ConfigureAwait(false);

        Console.WriteLine("Endpoint Started. Press s to send a very important message. Any other key to exit");

        var i = 0;

        while (Console.ReadKey(true).Key == ConsoleKey.S)
        {
            var message = new ImportantMessage
            {
                Text = $"Hello there: {i++}"
            };
            await endpoint.Send(message)
            .ConfigureAwait(false);
        }

        await endpoint.Stop()
        .ConfigureAwait(false);
    }
Beispiel #2
0
        public async Task Duplex_ManyParallelRequests_MessageRoundTripped()
        {
            const string ImportantMessage =
                @"       _____  _____   _____ 
       |  __ \|  __ \ / ____|
   __ _| |__) | |__) | |     
  / _` |  _  /|  ___/| |     
 | (_| | | \ \| |    | |____ 
  \__, |_|  \_\_|     \_____|
   __/ |                     
  |___/                      
  _                          
 (_)                         
  _ ___                      
 | / __|                     
 | \__ \          _          
 |_|___/         | |         
   ___ ___   ___ | |         
  / __/ _ \ / _ \| |         
 | (_| (_) | (_) | |         
  \___\___/ \___/|_|         
                             
                             ";

            var attempts          = 100;
            var allUploads        = new List <string>();
            var allCompletedTasks = new List <Task>();
            var tcs = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);

            async Task MessageUpload(
                IAsyncStreamReader <StringValue> requestStream,
                IServerStreamWriter <StringValue> responseStream,
                ServerCallContext context)
            {
                // Receive chunks
                var chunks = new List <string>();

                await foreach (var chunk in requestStream.ReadAllAsync())
                {
                    chunks.Add(chunk.Value);
                }

                Task completeTask;

                lock (allUploads)
                {
                    allUploads.Add(string.Join(Environment.NewLine, chunks));
                    if (allUploads.Count < attempts)
                    {
                        // Check that unused calls are canceled.
                        completeTask = Task.Run(async() =>
                        {
                            await tcs.Task;

                            var cancellationTcs = new TaskCompletionSource <bool>();
                            context.CancellationToken.Register(s => ((TaskCompletionSource <bool>)s !).SetResult(true), cancellationTcs);
                            await cancellationTcs.Task;
                        });
                    }
                    else
                    {
                        // Write response in used call.
                        completeTask = Task.Run(async() =>
                        {
                            // Write chunks
                            foreach (var chunk in chunks)
                            {
                                await responseStream.WriteAsync(new StringValue
                                {
                                    Value = chunk
                                });
                            }
                        });
                    }
                }

                await completeTask;
            }

            var method = Fixture.DynamicGrpc.AddDuplexStreamingMethod <StringValue, StringValue>(MessageUpload);

            var channel = CreateChannel(serviceConfig: ServiceConfigHelpers.CreateHedgingServiceConfig(maxAttempts: 100, hedgingDelay: TimeSpan.Zero), maxRetryAttempts: 100);

            var client = TestClientFactory.Create(channel, method);

            using var call = client.DuplexStreamingCall();

            var lines = ImportantMessage.Split(Environment.NewLine);

            for (var i = 0; i < lines.Length; i++)
            {
                await call.RequestStream.WriteAsync(new StringValue { Value = lines[i] }).DefaultTimeout();

                await Task.Delay(TimeSpan.FromSeconds(0.01)).DefaultTimeout();
            }
            await call.RequestStream.CompleteAsync().DefaultTimeout();

            await TestHelpers.AssertIsTrueRetryAsync(() => allUploads.Count == 100, "Wait for all calls to reach server.").DefaultTimeout();

            tcs.SetResult(null);

            var receivedLines = new List <string>();

            await foreach (var line in call.ResponseStream.ReadAllAsync().DefaultTimeout())
            {
                receivedLines.Add(line.Value);
            }

            Assert.AreEqual(ImportantMessage, string.Join(Environment.NewLine, receivedLines));

            foreach (var upload in allUploads)
            {
                Assert.AreEqual(ImportantMessage, upload);
            }

            await Task.WhenAll(allCompletedTasks).DefaultTimeout();
        }