C# .NET - How to handle multiple requests simultaneously using HttpListeners

Asked By Sachin Mishra
19-Nov-08 02:12 AM

How to handle multiple requests simultaneously using HttpListeners ? I am working on an application which listen the http request but how will have to implement the multiple request simultaneously processed by the client application at same time.

 

 

re  re

19-Nov-08 02:18 AM
webservice that will receive/process multiple
client requests simultaneously. For this purpose, I wrote the following
code, but it does not seem to be handling more than two at a time. I
put in a few console prints and have also attached the output. Here it
goes -

public void serverStart() {

   HttpListener _listener = new HttpListener();

   _listener.Prefixes.Add(.......);

   _listener.Start();

   while (true)

       ProcessRequest();

}

public void ProcessRequest()

{

    Console.WriteLine("PR " + ++count); //count initialized to 0 in
beginning

    IAsyncResult result = _listener.BeginGetContext(new AsyncCallback
ListenerCallback),this._listener);

    result.AsyncWaitHandle.WaitOne();

}

protected void ListenerCallback(IAsyncResult result)

{

    if (this._listener == null) return;

    HttpListenerContext context = this._listener.EndGetContext(result);

    Console.WriteLine("LC " + count);

    this.ProcessRequest2(context);

}

public void ProcessRequest2(HttpListenerContext ctx)

{

    Console.WriteLine("PR2 " + count);

    string str = ctx.Request.HttpMethod;

    HttpListenerWorkerRequest workerRequest =

    new HttpListenerWorkerRequest(ctx,_virtualDir, _physicalDir,
_logCallback, _pxeb);

    HttpRuntime.ProcessRequest(workerRequest);

}

use HttpListener  use HttpListener

19-Nov-08 02:19 AM
HttpListener allows only one request to be handled concurrently?
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.IO;
 
sealed class HttpServer
{
public static void Main()
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:" + 1234 + "/");
listener.Start();
for(int i =0; i< 10; i++)
{
IAsyncResult result = listener.BeginGetContext(new AsyncCallback(HttpWorker.Handle), listener);
}
Console.WriteLine("Press ENTER to quit.");
Console.Read();
}
}
public class HttpWorker{
 
public static void Handle(IAsyncResult ar)
{
HttpListener listener = (HttpListener) ar.AsyncState;
try
{
HttpListenerContext context = listener.EndGetContext(ar);
StreamWriter writer = new StreamWriter(context.Response.OutputStream);
writer.Write("<html><body>");
writer.Write("This call was handled in " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
writer.Write("<br>");
writer.Write("Done");
writer.Write("</body></html>");
writer.Close();
context.Response.OutputStream.Close();
context.Response.Close();
}
finally
{
listener.BeginGetContext(new AsyncCallback(HttpWorker.Handle), listener);
}
}
}
 

Re :: Handle multiple requests simultaneously using HttpListeners  Re :: Handle multiple requests simultaneously using HttpListeners

19-Nov-08 02:19 AM

See the following articles

http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/b6108c08-fe15-4692-9392-248b91a95dea/

http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic57727.aspx

Hope this helps.

read this  read this
19-Nov-08 02:26 AM

Ok the question you are asking is a bit tricky.  Deep down httplistener is using IOCompletion ports.  You can easily verify this yourself by placing the following code in your Handle function.

int ioThreads, workerThreads;

System.Threading.ThreadPool.GetAvailableThreads( out workerThreads, out ioThreads );

Console.WriteLine( "IOThreads: " + ioThreads.ToString() + " WorkerThreads: " + workerThreads.ToString() );

System.Threading.ThreadPool.GetMaxThreads( out workerThreads, out ioThreads );

Console.WriteLine( "IOThreadsMax: " + ioThreads.ToString() + " WorkerThreadsMax: " + workerThreads.ToString() );

you should see that the available IO threads are 999 and the max is 1000 which means that your request is coming in on an iothread (if it wasn't you would see the worker threads are 1 less than max), typically you only use 1 io thread per cpu with a 1 overflow so 2 per cpu.  I have no idea what rules the OS uses to decide if needs to use that 1 io thread overflow .  Plus you are using Sleep which may also be causing erroneous behaviour. 

Basically you are placing the sleep there to mimic work am I correct?

Problem is that Thread.Sleep is a very poor example for the system "working" its just not treated the same.  I suggest a different test.  Perhaps using microsofts free load tester and take the sleep out and see how many connections you can handle per second.  That is far better test for a system.  That is unless all you are trying to prove is that two requests on httplistener are happening at the same exact time.
How to handle multiple requests simultaneously using HttpListeners  How to handle multiple requests simultaneously using HttpListeners
20-Nov-09 01:35 PM

Hello,

I also saw that only two requests could be handled at a time by HttpListener.

To get around this, use the following.  I now have 10 executing at the same time with HttpListener.  The solution involves making a change to the registery.

1. Start the registry editor.

2. Locate the following key in the registry:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings

3. On the Edit menu, point to New, click DWORD Value, and then add the following registry values:

Value name: MaxConnectionsPer1_0Server

Value data: 10

Base: Decimal

Value name: MaxConnectionsPerServer

Value data: 10

Base: Decimal

4. Exit the registry.

 

 

Create New Account
help
NET 2.0, SqlClient. When the BeginXXX method is used, the Result Method(params) becomes: IAsyncResult BeginMethod(params, callback, state)Result EndMethod(IAsyncResult) The .NET 2.0 Framework and above offer us a new Event-based Asynchronous programming model that makes asynchronous programming more friendly to the average developer (no IAsyncResult / AsyncCallback). It is Implemented by some .NET components including Web Service proxies. In .NET 2 based pattern. It offers the lower level API for developers who prefer to implement the IAsyncResult / IAsyncCallback pattern. The disadvantages are that the Framework pattern is the least developer-friendly. It culture, or the HttpContext to the "end handler", and it is difficult to combine multiple IAsyncResult objects. The ASP.NET 2.0 Event-based Asynchronous model looks like this: On Page_Load using System.IO; public partial class samples_MultiWebRequest : System.Web.UI.Page { HttpWebRequest req1; HttpWebRequest req2; IAsyncResult result1; IAsyncResult result2; DataSet ds1 = new DataSet(); DataSet ds2 = new DataSet(); protected void Page_Load(object sender, EventArgs void OnPreRenderComplete(EventArgs e) { base .OnPreRenderComplete(e); / / write the result messages to the Label. MessageOut(); } IAsyncResult BeginAsyncWork1(Object sender, EventArgs e, AsyncCallback cb, object state) { AddTraceMessage( "BeginAsyncWork" ); AddTraceMessage( "BeginGetRSSOne" ); this .req1
let’s create an asynchronous OrderService. [ServiceContract(Name = "IOrderService" )] public interface IAsyncOrderService { [OperationContract(AsyncPattern = true )] IAsyncResult BeginGetOrder(int orderId, AsyncCallback callback, object asyncState); Order EndGetOrder(IAsyncResult result); } Listing 8. Asynchronous Order Service Same thing we did with the IOrderService, we will orderService = orderService; } public void BeginGetOrder(int orderId) { orderService.BeginGetOrder(orderId, GetOrderCallback, null ); } private void GetOrderCallback(IAsyncResult result) { Order order = orderService.EndGetOrder(result); var eh = GetOrderCompleted; if (eh ! = null ) eh( this , new Mock<IAsyncOrderService> orderService; [SetUp] public void Setup() { orderService = new Mock<IAsyncOrderService> (MockBehavior.Strict); orderService .Setup<IAsyncResult> (o = > o.BeginGetOrder(It.IsAny<int> (), It.IsAny<AsyncCallback> (), It.IsAny<object> ())) .Returns(() = > new Mock<IAsyncResult> ().Object) .Callback ( (int orderId, AsyncCallback callback, object asyncState) = > { orderService .Setup<Order> (os = > os.EndGetOrder(It IsAny<IAsyncResult> ())) .Returns( new Order { Id = orderId }); var result = new Mock<IAsyncResult> (); callback.BeginInvoke(result.Object, null , null ); } ); } [ Test ] public void GetOrderTest() { var client = new AsyncOrderClient(orderService Set(); }; client.BeginGetOrder(1); waitHandle.WaitOne(); waitHandle.Dispose(); Assert.AreEqual(asyncOrder.Id, 1); orderService.Verify<IAsyncResult> (o = > o.BeginGetOrder(It.IsAny<int> (), It.IsAny<AsyncCallback> (), It.IsAny<object> ()), Times.Once()); orderService
listener.Start(); Console.WriteLine( "Listening. . ." ); / / Note: The GetContext method blocks while waiting for a request. HttpListenerContext context = listener.GetContext(); HttpListenerRequest request = context.Request; / / Obtain a response object. while ( true ) { HttpListenerResponse response = context.Response; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestString); / / setup removed for brevity KeyValuePair<HttpWebRequest , HttpListenerContext > cookie = new KeyValuePair<HttpWebRequest HttpListenerContext > (request, context); IAsyncResult result = (IAsyncResult)request.BeginGetResponse( new AsyncCallback(RequestCallback), cookie); } } listener.Stop(); } static void RequestCallback(IAsyncResult asynchronousResult) { / / State of request is asynchronous. KeyValuePair<HttpWebRequest , HttpListenerContext > cookie = (KeyValuePair<HttpWebRequest , HttpListenerContext > )asynchronousResult.AsyncState; Console.WriteLine( "Got back response from " + requestData.Context.Request.Url.AbsoluteUri); using (HttpWebResponse