Exemple #1
0
        private static async Task Main()
        {
            _server = new Server(CancellationTokenSource);

            var listener = new TcpListener(IPAddress.Loopback, Port);

            listener.Start();

            Console.WriteLine($"Server started on port: {Port}.");

            var requestTasks = new HashSet <Task>();

            while (!CancellationTokenSource.IsCancellationRequested)
            {
                try
                {
                    //With wait cancellation allows to cancel the acceptTcpClientAsync, if the server is currently
                    //waiting for more connections and someone already shut it down
                    var client = await listener
                                 .AcceptTcpClientAsync()
                                 .WithWaitCancellation(CancellationTokenSource.Token);

                    //used to let the client know that he is now connected
                    //server "handshake"
                    await WriteResponse(client.GetStream(),
                                        ResponseFactory.SuccessResponse("Connection established with success."));

                    Console.WriteLine($"connection accepted with id: {_connectionIdCounter++}.\n");

                    //add the client to a task container "requestTasks" that will be awaited on server shutdown
                    requestTasks.Add(HandleResponse(client, _connectionIdCounter));

                    //if the server limit was reached stop receiving more requests until one of the current ones finishes
                    if (requestTasks.Count == MaximumConcurrentClients)
                    {
                        requestTasks.Remove(await Task.WhenAny(requestTasks));
                    }
                }
                catch (OperationCanceledException)
                {
                    //on cancellation a shutdown is occurring, no need to handle the exception
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Unknown error: {e.Message}");
                }
            }

            //wait for all tasks to be completed except the one that initiated the shutdown
            while (requestTasks.Count > 1)
            {
                requestTasks.Remove(await Task.WhenAny(requestTasks));
            }

            //terminates the timeout on server shutdown
            _server.NotifyServerShutdownIsComplete();

            //Wait for the last task to complete
            await Task.WhenAny(requestTasks);

            listener.Stop();

            Console.Write("Server shutdown successful.\n");
        }