Exemple #1
0
        static async Task Main(string[] args)
        {
            var listener   = new TcpListener(IPAddress.Loopback, port);
            var terminator = new Terminator();
            var cts        = new CancellationTokenSource();
            var ct         = cts.Token;

            Console.CancelKeyPress += (obj, eargs) =>
            {
                Log("CancelKeyPress, stopping server");
                cts.Cancel();
                listener.Stop();
                eargs.Cancel = true;
            };
            listener.Start();
            Log($"Listening on {port}");
            using (ct.Register(() => { listener.Stop(); }))
            {
                try
                {
                    while (!ct.IsCancellationRequested)
                    {
                        Log("Accepting new TCP client");
                        var client = await listener.AcceptTcpClientAsync();

                        var id = counter++;
                        Log($"connection accepted with id '{id}'");
                        Handle(id, client, ct, terminator);
                    }
                }
                catch (Exception e)
                {
                    // await AcceptTcpClientAsync will end up with an exception
                    Log($"Exception '{e.Message}' received");
                }

                Log("waiting shutdown");
                await terminator.Shutdown();
            }
        }
Exemple #2
0
        private static async void Handle(
            int id,
            TcpClient client,
            CancellationToken cancellationToken,
            Terminator terminator)
        {
            using (terminator.Enter())
            {
                try
                {
                    using (client)
                    {
                        var stream = client.GetStream();
                        var reader = new JsonTextReader(new StreamReader(stream))
                        {
                            // To support reading multiple top-level objects
                            SupportMultipleContent = true
                        };
                        var writer = new JsonTextWriter(new StreamWriter(stream));
                        while (true)
                        {
                            try
                            {
                                // to consume any bytes until start of object ('{')
                                do
                                {
                                    await reader.ReadAsync(cancellationToken);

                                    Log($"advanced to {reader.TokenType}");
                                } while (reader.TokenType != JsonToken.StartObject &&
                                         reader.TokenType != JsonToken.None);

                                if (reader.TokenType == JsonToken.None)
                                {
                                    Log($"[{id}] reached end of input stream, ending.");
                                    return;
                                }

                                Log("Reading object");
                                var json = await JObject.LoadAsync(reader, cancellationToken);

                                Log($"Object read, {cancellationToken.IsCancellationRequested}");
                                var      request  = json.ToObject <Request>();
                                Response response = null;
                                switch (request.Method)
                                {
                                case "ECHO":
                                    response = Echo(request, json);
                                    break;

                                case "DELAY":
                                    response = await Delay(request);

                                    break;

                                default:
                                    response = new Response()
                                    {
                                        Status = 405
                                    };
                                    break;
                                }

                                serializer.Serialize(writer, response);
                                await writer.FlushAsync(cancellationToken);
                            }
                            catch (JsonReaderException e)
                            {
                                Log($"[{id}] Error reading JSON: {e.Message}, ending");
                                var response = new Response
                                {
                                    Status = 400,
                                };
                                serializer.Serialize(writer, response);
                                await writer.FlushAsync(cancellationToken);

                                // close the connection because an error may not be recoverable by the reader
                                return;
                            }
                            catch (Exception e)
                            {
                                Log($"[{id}] Exception: {e.Message}, ending");
                                return;
                            }
                        }
                    }
                }
                finally
                {
                    Log($"Ended connection {id}");
                }
            }
        }
 public TerminatorDisposable(Terminator terminator)
 {
     this.terminator = terminator;
 }