Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Net.HttpListener on Windows 7 Ultimate x64 Limited to 1k Concurrent Connections

I've been trying to do some testing with the HTTP.sys / HttpListener on my workstation and it seems that there is some limit in place that prevents more that 1000 concurrent connections. Does anyone have any more information about this? (As 1k seems a little to clean to be a coincidence).

I've tried to find any thread / config / registry setting but have come up empty.

Thanks in advance.
GJ


Looks like I jumped the gun a bit.

I seem to have missed that using http.sys / HttpListener BeginGetContext isn't very good for concurrent connections as the new BeginGetContext will only fire after the response stream from the prior request has closed.

So there is a backlog of 1000 requests, and in this case the backlog was filling up.

Anyhow - if anyone has any comments (or likely corrections) feel free to expand.

Thanks
GJ

like image 584
CameraSchoolDropout Avatar asked Nov 10 '10 14:11

CameraSchoolDropout


1 Answers

The way I've done it is to have a thread that listens on the HttpListener using the blocking GetContext() method but as soon as it receives a request passes it off to another thread by doing an async invoke using the IAsyncResult pattern and this seems to work fine.

    private void Run()
    {
        while (true)
        {
            if (this._disposed || this._shouldTerminate) return;

            if (this._listener.IsListening)
            {
                try
                {
                    HttpListenerContext context = this._listener.GetContext();

                    //Hand it off to be processed asynchronously
                    this._delegate.BeginInvoke(context, new AsyncCallback(this.EndRequest), null);
                }
                catch (Exception ex)
                {
                    this.LogErrors(ex);
                }
            }
        }
    }

    private delegate HttpServerContext HandleRequestDelegate(HttpListenerContext context);

    private HttpServerContext HandleRequest(HttpListenerContext context)
    {
        IHttpListenerHandler handler;
        HttpServerContext serverContext = new HttpServerContext(this, context);
        try
        {
            bool skipHandling = this.ApplyPreRequestModules(serverContext);
            if (!skipHandling)
            {
                handler = this._handlers.GetHandler(serverContext);
                handler.ProcessRequest(serverContext);
            }
        }
        catch (NoHandlerException noHandlerEx)
        {
            this.LogErrors(noHandlerEx);
            context.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;
        }
        catch (HttpServerException serverEx)
        {
            this.LogErrors(serverEx);
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        }

        return serverContext;
    }

    private void EndRequest(IAsyncResult result)
    {
        try
        {
            HttpServerContext context = this._delegate.EndInvoke(result);
            this.ApplyPreResponseModules(context);
            context.Response.Close();
        }
        catch (Exception ex)
        {
            this.LogErrors(ex);
        }
    }
like image 55
RobV Avatar answered Sep 30 '22 17:09

RobV