c# – 多线程HttpListener,等待异步和任务 - 代码日志

c# – 多线程HttpListener,等待异步和任务

这可能是一个可扩展的HttpListener的一个很好的例子,它是多线程的?

这是怎么例如一个真正的IIS会这样做的?

public class Program
{
    private static readonly HttpListener Listener = new HttpListener();

    public static void Main()
    {
        Listener.Prefixes.Add("http://+:80/");
        Listener.Start();
        Listen();
        Console.WriteLine("Listening...");
        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }

    private static async void Listen()
    {
        while (true)
        {
            var context = await Listener.GetContextAsync();
            Console.WriteLine("Client connected");
            Task.Factory.StartNew(() => ProcessRequest(context));
        }

        Listener.Close();
    }

    private static void ProcessRequest(HttpListenerContext context)
    {
        System.Threading.Thread.Sleep(10*1000);
        Console.WriteLine("Response");
    }
}

我专门寻找一种不依赖于IIS的可扩展解决方案。而只是在http.sys(这是httplistener类) – 不依赖于iIS的原因是因为政府。我工作的地区需要极大的减少表面积的攻击。

我在https://github.com/JamesDunne/Aardwolf做了类似的事情,并做了一些广泛的测试。

核心事件循环的实现见代码https://github.com/JamesDunne/aardwolf/blob/master/Aardwolf/HttpAsyncHost.cs#L107

我发现使用信号量来控制多少并发GetContextAsync请求是活动的是最好的方法。基本上,主循环继续运行,直到信号量阻止线程由于到达计数。那么会有N个并发的“连接接受”活动。每次连接被接受时,信号量被释放,并且新的请求可以取代它。

信号灯的初始和最大计数值需要进行一些微调,具体取决于您希望接收的负载。这是您期望的并发连接数与您的客户所期望的平均响应时间之间的微妙平衡。更高的值意味着更多的连接可以保持在一个非常慢的平均响应时间;较少的连接将被拒绝。较低的值意味着较少的连接可以保持在更快的平均响应时间;更多的连接将被拒绝。

我发现,在实验(在我的硬件上),大约128的值允许服务器在可接受的响应时间处理大量并发连接(最多1,024)。使用自己的硬件进行测试并相应地调整参数。

我也发现WCAT的一个实例不喜欢处理超过1,024个连接本身。因此,如果您认真进行负载测试,请在服务器上使用具有WCAT的多台客户端计算机,并确保通过快速网络进行测试。 10GbE,并且您的操作系统的限制并不会让您失望。确保在Windows Server SKU上进行测试,因为桌面SKU默认是受限制的。

概要:
如何编写连接接受循环对于服务器的可扩展性至关重要。

http://stackoverflow.com/questions/11167183/multi-threaded-httplistener-with-await-async-and-tasks

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c# – 多线程HttpListener,等待异步和任务