Thursday, April 14, 2011

How to create a HTTP request listener Windows Service in .NET

I want to create Windows Service that acts as a HTTP listener and can handle around 500 clients. Are there any special considerations for this kind of service.

I am a little confused between the HTTPListener class and the TCPListener class. Which one to use for a Windows Service that will:

  1. Accept the client connection (around 500)
  2. Process client request
  3. Call another Http based service
  4. Return some value to the calling client


This is what I am doing to start the listener.

    listener = new HttpListener();
    listener.Prefixes.Add("http://localhost:8080/");
    listener.Start();
    listener.BeginGetContext(new AsyncCallback(OnRequestReceive), listener);

private void OnRequestReceive(IAsyncResult result)
{
     HttpListener listener = (HttpListener)result.AsyncState;
     // Call EndGetContext to complete the asynchronous operation.
     HttpListenerContext context = listener.EndGetContext(result);
     HttpListenerRequest request = context.Request;
}

Will I be able to handle N clients simultaneously?

From stackoverflow
  • I'd use HttpListener class. It does many stuff for you and you wouldn't need to reinvent the wheel. Also it integrates with kernel mode http.sys driver in Windows Server 2003 and should offer better performance.

  • If you need to be able to highly responsive HttpListener will not scale very well (you cannot accept more than one connection at a time). But for small scale use, being careful to get context and write the response asynchronously it can work.

    EDIT: Appears I misunderstood HttpListener's ability to accept connections. You can accept multiple connections concurrently (see comment). However IIS's other facilities to host code would avoid reinventing the wheel. So unless there are very specific requirements that preclude IIS, why not take the easy path?

    For serious use, use IIS, creating an Http Handler (a class that implements IHttpHandler or IHttpHandlerFactory, or even an IHttpAsyncHandler) to handle the requests (this is the underlying type that implements .aspx et al).

    The right solution really depends on what you mean by "handle around 500 clients": one at a time or all at once?

    Based on the comment answer: 500 at once, and noting that the processing, in step 3, includes another HTTP call, I doubt using HttpListner will be able to handle the load without ensuring every operation is asynchronous (getting context and request, performing the onward HTTP request and then sending the response)... which will lead to some more difficult coding.

    Unless there is a very good reason to avoid IIS, using IIS will be easier as it is designed to support large scale client request loads with rich functionality, whereas HttpListener "Provides a simple, programmatically controlled HTTP protocol listener.".

    EDIT: Expanded based on more details of load.

    A9S6 : I mean 1-500 clients can be connected to that Service at any given time. Also, the processing time of each client will be small.
    Darrel Miller : Can you provide some source that claims that HttpListener cannot accept more than one connection at a time? I have running code using HttpListener that appears to me to be handling multiple requests concurrently. By calling BeginGetContext multiple times you effectively setup multiple listeners. Also, HttpListener is based on http.sys which is identical to what IIS uses for serving requests, so the performance should be equivalent.
    Richard : Added note to that effect, thank's for the update.
  • I created a TcpListener and started the listener using BeginAcceptTcpClient method. Each incoming request is taken to a separate thread for processing where the client connection is used continuously to get/send data from client. It seems to be working fine for large number of clients.

0 comments:

Post a Comment