private static async Task TimePingWithGoodBye(string userName, TimeInformationService.TimeInformationServiceClient client)
        {
            Console.Write("How long should i wait? (seconds): ");
            var waitTime = double.Parse(Console.ReadLine());

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       token = cancellationTokenSource.Token;

            CancelApplication(cancellationTokenSource);

            using (var call = client.TimePingWithGoodBye())
            {
                var outputTask = Task.Run(() => PrintReponse(call.ResponseStream));

                while (!token.IsCancellationRequested)
                {
                    await call.RequestStream.WriteAsync(new TimePingRequest()
                    {
                        ClientName = userName
                    });

                    await Task.Delay(TimeSpan.FromSeconds(waitTime));
                }

                await call.RequestStream.WriteAsync(new TimePingRequest()
                {
                    ClientName = userName, GoodBye = true
                });

                await call.RequestStream.CompleteAsync();

                await outputTask;
            };
        }
        private static async Task TimePingWithCancellationToken(string userName, TimeInformationService.TimeInformationServiceClient client)
        {
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       token = cancellationTokenSource.Token;

            using (var response = client.TimePing(new TimePingRequest()
            {
                ClientName = userName
            }))
            {
                CancelApplication(cancellationTokenSource);

                try
                {
                    while (await response.ResponseStream.MoveNext(token))
                    {
                        TimePingReply timePingReply = response.ResponseStream.Current;
                        Console.WriteLine($"{timePingReply.TimeNow.ToDateTimeOffset().ToString()} : {timePingReply.Message}");
                    }
                }
                catch (RpcException e)
                {
                    if (e.StatusCode != StatusCode.Cancelled)
                    {
                        throw;
                    }
                }
            }
        }
        static async Task Main(string[] args)
        {
            AppContext.SetSwitch(
                "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

            IConfigurationRoot configuration = ReadConfiguration();
            var serverUrl = GetServerUrl(configuration);

            Console.Write("What is your name?: ");
            var userName = Console.ReadLine();

            var channel = GrpcChannel.ForAddress(new Uri(serverUrl), new GrpcChannelOptions()
            {
                Credentials = ChannelCredentials.Insecure
            });

            TimeInformationService.TimeInformationServiceClient client = new TimeInformationService.TimeInformationServiceClient(channel);
            await TimePingWithCancellationToken(userName, client);

            // await TimePingWithGoodBye(userName, client);
        }