Ejemplo n.º 1
0
        internal async Task Run()
        {
            var certificate = CertificateBuilder.Build(Attribute.Hostname);
            var listener    = new TcpListener(IPAddress.Loopback, Attribute.Port);

            listener.Start();

            Log.I($"[{Identifier}:{Attribute.Type}] Listening on {Attribute.Hostname}:{Attribute.Port}");

            while (true)
            {
                // Log.D($"[{Identifier}] Waiting for new connection");
                var client = await listener.AcceptTcpClientAsync();

                // Log.D($"[{Identifier}] Got connection from {client.Client.RemoteEndPoint}");
                var sslStream = new SslStream(client.GetStream(), false);
                try
                {
                    await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls12, false);

                    sslStream.ReadTimeout  = 5000;
                    sslStream.WriteTimeout = 5000;

                    using (var reader = new StreamReader(sslStream))
                    {
                        IAsyncEnumerator <byte[]> responses = null;

                        switch (Attribute.Type)
                        {
                        case HandlerType.Http:
                            responses = HandleHttpRequest(reader);
                            break;

                        case HandlerType.Ws:
                            responses = HandleWsRequest(reader);
                            break;
                        }

                        try
                        {
                            await responses.ForEachAsync(
                                async response => await sslStream.WriteAsync(response, 0, response.Length));
                        }
                        catch (TaskCanceledException) { }
                    }
                }
                catch (Exception ex)
                {
                    Log.Ex(ex, $"Exception occured while handling request on {Identifier} ");
                }
                finally
                {
                    sslStream.Dispose();
                    client.Close();
                }
            }
        }
Ejemplo n.º 2
0
 public override IAsyncEnumerator <bool> ConsumeFlow(IAsyncEnumerator <TDroplet> flow)
 {
     return(new AsyncEnumerator <bool>(async yield =>
     {
         await flow.ForEachAsync(async t =>
         {
             bool stored = await ConsumeDroplet(t);
             await yield.ReturnAsync(stored);
         });
     }));
 }
Ejemplo n.º 3
0
 public static async Task UntilAsync <T>(this IAsyncEnumerator <T> e, Func <T, bool> until, AsyncEnumerator <T> .Yield yield = null)
 {
     await e.ForEachAsync(t =>
     {
         if (!until(t))
         {
             if (yield != null)
             {
                 yield.Break();
             }
             e.Dispose();
         }
     });
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Collects the elements of an IAsyncEnumerator into a regular enumerable.
        /// </summary>
        public static async Task <IProducerConsumerCollection <T> > Collect <T>(this IAsyncEnumerator <T> e, int maxCount = 0)
        {
            var queue = new ConcurrentQueue <T>();
            await e.ForEachAsync(t =>
            {
                queue.Enqueue(t);
                if (--maxCount == 0)
                {
                    e.Dispose();
                }
            });

            return(queue);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Pipes an input flow into this component, then returns the piped output flow.
 /// </summary>
 public virtual IAsyncEnumerator <TOutput> PipeFlow(IAsyncEnumerator <TInput> flow, Predicate <TOutput> stop = null, int maxDroplets = 0)
 {
     // The default implementation is 1-1 dripping, while FlowMachines have a tailored and more efficient nInputs:nOutputs flowing implementation.
     return(new AsyncEnumerator <TOutput>(async yield =>
     {
         await flow.ForEachAsync(async t =>
         {
             await ConsumeDroplet(t);
             TOutput ret = await Drip();
             if (!IsFlowStarted || (stop?.Invoke(ret) ?? false) || --maxDroplets == 0)
             {
                 yield.Break();
             }
             await yield.ReturnAsync(ret);
         });
     }));
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Similar to (and calls) ConsumeFlow, but staunches the flow as soon as a certain droplet is found in the input flow, then starts it again.
 /// This is a piping tool and should not be used directly by consumers.
 /// </summary>
 public static IAsyncEnumerator <bool> ConsumeFlowUntilDroplet <T>(this IFlowConsumer <T> c, IFlowProducer <T> producer, IAsyncEnumerator <T> flow, Predicate <T> stopOn)
 {
     return(new AsyncEnumerator <bool>(async yield =>
     {
         if (producer.IsFlowStarted && producer is FlowProducerBase <T> prodImpl)
         {
             await c.ConsumeFlow(new AsyncEnumerator <T>(async innerYield =>
             {
                 await flow.ForEachAsync(async d =>
                 {
                     if (stopOn(d))
                     {
                         innerYield.Break();
                     }
                     await innerYield.ReturnAsync(d);
                 });
             })).UntilAsync(async b =>
             {
                 await yield.ReturnAsync(b);
                 return b;
             }, yield);
         }
     }));
 }