2

MSDN 说HttpListener 基于 http.sys 并且“HTTP.sys 提供连接管理、带宽限制和 Web 服务器日志记录”。

我需要限制与服务器的最大连接数。使用 HttpListener 执行此操作的最佳方法是什么?

4

2 回答 2

1

如果您使用 HttpListener,这意味着您负责提供请求/响应处理。如果您要在应用程序中创建新的HttpListener实例,添加前缀并调用 Start,直到您的代码调用 GetContext 或 BeginGetContext,您的应用程序代码才会响应传入请求。

如果您调用 BeginGetContext (async),它将只处理一个请求,直到再次调用 BeginGetContext。所以它自然受到限制(仅限于一个连接)。如果您调用它两次,它将处理两个,依此类推。虽然连接尝试可以“排队”,但一次只能处理一个。

于 2012-02-25T20:31:03.327 回答
0

HttpListener 维护一个待处理连接的内部队列,因此简单地“不接受连接”在这里没有帮助,您需要清除它的队列。这可以通过线程池 (.NET <= 4.0) 或异步连接 (4.5+) 进行管理。

“线程池+队列”方法的一个例子是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。

于 2015-10-22T20:27:15.663 回答