HttpListener душит? - PullRequest
       18

HttpListener душит?

2 голосов
/ 20 декабря 2011

MSDN говорит HttpListener основан на http.sys и «HTTP.sys обеспечивает управление подключениями, регулирование пропускной способности и ведение журнала веб-сервера.»

Мне нужно ограничить максимальное количествоподключения к серверу.Каков наилучший способ сделать это с HttpListener?

Ответы [ 2 ]

1 голос
/ 26 февраля 2012

Если вы используете HttpListener, это означает, что вы несете ответственность за обеспечение обработки запросов / ответов.Если вам нужно создать новый экземпляр HttpListener в своем приложении, добавить префикс и вызвать Start, то только в том случае, если ваш код вызовет GetContext или BeginGetContext, код вашего приложения будет отвечать на входящий запрос.

Если вы вызываете BeginGetContext (async), он будет обрабатывать только один запрос, пока BegingGetContext не будет вызван снова.Так что это естественно ограничено (только одно соединение).Если бы вы назвали это дважды, он бы обработал два, и так далее.Хотя попытки подключения могут быть «поставлены в очередь», они будут обрабатываться только по одной за раз.

0 голосов
/ 22 октября 2015

HttpListener поддерживает внутреннюю очередь ожидающих соединений, поэтому простое «непринятие соединения» здесь не поможет, вам нужно очистить его очередь.Это может управляться с помощью пула потоков (.NET <= 4.0) или с помощью асинхронных соединений (4.5 +). </p>

Примером подхода «пул потоков + очередь» является Grapevine .В моей ветке исследований и разработок Interpspecific я улучшил это, чтобы ограничить количество ожидающих запросов.Он очищает очередь HttpListener и отклоняет запросы с 500 ошибками, если очередь заполнена.Начиная с RESTServer.c :

    private void HandleRequests()
    {
        // Immediately accept and handle any requests:
        while (this.IsListening)
        {
            try
            {
                var context = this._listener.GetContext();
                this.QueueRequest(context);
            }
            catch (Exception e)
            {
                EventLogger.Log(e);
            }
        }
    }

    private void QueueRequest(HttpListenerContext context)
    {
        lock (this._queue)
        {
            if (_queue.Count > MaxPendingRequests)
            {
                context.Response.StatusCode = 503;
                context.Response.OutputStream.Close();
                context.Response.Close();
                EventLogger.Log(
                    String.Format( "Request queue max size reached: {0}. Connection refused with 503 error.", 
                                   MaxPendingRequests ) );
                return;
            }

            this._queue.Enqueue(context);
            this._ready.Set();
        }
    }

Это ограничивает общее количество подключений к MaxPendingRequests + количество потоков, извлекающих подключения из очереди.Потоки Hanlder вытаскивают из очереди (оставлены в качестве упражнения для читателя или см. RESTServer.c для примеров).

Цикл принятия и предел подключения будут другими, если вы используете асинхронный подход (гораздо более масштабируемый)но только 4.5+), но общая идея та же: немедленно принять HttpListenerContexts и вернуть 500, если вы «слишком заняты».

...