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:
- Accept the client connection (around 500)
- Process client request
- Call another Http based service
- 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?
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.
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.
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.
BeginGetContext accepts just one request. You need to repeat the async call everytime you receive a request so that you proceed more than a single request.
Some people simplify their design by having a listener thread which synchronously waits (i.e. use the synchronous GetContext) in a loop. It's not a nice design as you end up having a thread sitting there waiting (waste of system resources), but it may be acceptable if you are not religious about performance / for a proof-of-concept implementation.
You also need to place a listener.Close() call in your service shutdown method. Careful to synchronize this with the possible asynchronous threads processing requests.