I have implemented an asynchronous http listener in c#.
I followed the tutorial provided here by Microsoft
and found another tutorial which i stupidly not bookmarked and now can't find again. Meaning that I have some code that I would not have written that way myself but the explanations provided made sense so I followed that.
Now I am facing two problems:
First, I have to restart the listener after each request with Listener.Stop() and then call the StartListening method and again and second, when I do this, I receive each request twice. The request does net get sent twice, but I receive it twice. It does not however get received twice when I pause the Thread I am listening on for about 2 seconds.
I am sorry if I am quite vague in my explanations, but so is my understanding of my problem, I have no idea what is causing it. Since the callback method is where most of the stuff happens, I will just post it, please tell me if you need any more code. Any help will be gladly appreciated, since I am really stuck on this one.
public void ListenAsynchronously()
{
if (listener.Prefixes.Count == 0) foreach (string s in prefixes) listener.Prefixes.Add(s);
try
{
listener.Start();
}
catch (Exception e)
{
Logging.logException(e);
}
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Listen));
}
private void Listen(object state)
{
while (listener.IsListening)
{
listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
listenForNextRequest.WaitOne();
}
}
private void ListenerCallback(IAsyncResult ar)
{
HttpListener httplistener = ar.AsyncState as System.Net.HttpListener;
System.Net.HttpListenerContext context = null;
int requestNumber = System.Threading.Interlocked.Increment(ref requestCounter);
if (httplistener == null) return;
try
{
context = httplistener.EndGetContext(ar);
}
catch(Exception ex)
{
return;
}
finally
{
listenForNextRequest.Set();
}
if (context == null) return;
System.Net.HttpListenerRequest request = context.Request;
if (request.HasEntityBody)
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(request.InputStream, request.ContentEncoding))
{
string requestData = sr.ReadToEnd();
//Stuff I do with the request happens here
}
}
try
{
using (System.Net.HttpListenerResponse response = context.Response)
{
//response stuff happens here
}
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.LongLength;
response.OutputStream.Write(buffer, 0, buffer.Length);
response.Close();
StopListening();
//If I dont set the thread to sleep here, I receive the double requests
System.Threading.Thread.Sleep(2500);
ListenAsynchronously();
}
}
catch (Exception e)
{
}
}
I am not sure why you are calling
StopListening()
andListenAsynchronously()
in yourListenerCallback()
method. TheListen()
method is being run in a thread and will continue to get each next incoming request. If I was writing this, I would not be using a instance variable of HttpListener. Create a new one in your ListenAsynchronously method and pass it in your state object, for example,