C# 异步HttpListener要求每个请求接收两次
我在c#中实现了一个异步http侦听器 我遵循了提供的教程 发现了另一个教程,我愚蠢地没有书签,现在找不到了。这意味着我有一些代码,我自己不会这样写,但提供的解释是有意义的,所以我遵循了这一点 现在我面临两个问题: 首先,我必须在每次请求后使用listener.Stop()重新启动侦听器,然后再次调用StartListening方法;其次,当我这样做时,我会收到每个请求两次。 请求确实发送了两次,但我收到了两次。 但是,当我暂停正在侦听的线程大约2秒时,不会收到两次 我很抱歉,如果我的解释很模糊,但我对我的问题的理解也是如此,我不知道是什么原因造成的。 由于回调方法是大部分事情发生的地方,我将发布它,如果您需要更多的代码,请告诉我。 任何帮助都会非常感激,因为我真的被困在这一点上了C# 异步HttpListener要求每个请求接收两次,c#,.net,http,httpclient,C#,.net,Http,Httpclient,我在c#中实现了一个异步http侦听器 我遵循了提供的教程 发现了另一个教程,我愚蠢地没有书签,现在找不到了。这意味着我有一些代码,我自己不会这样写,但提供的解释是有意义的,所以我遵循了这一点 现在我面临两个问题: 首先,我必须在每次请求后使用listener.Stop()重新启动侦听器,然后再次调用StartListening方法;其次,当我这样做时,我会收到每个请求两次。 请求确实发送了两次,但我收到了两次。 但是,当我暂停正在侦听的线程大约2秒时,不会收到两次 我很抱歉,如果我的解释很模糊
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)
{
}
}
我不知道您为什么在
ListenerCallback()
方法中调用stopstening()
和ListenAsynchronously()
。Listen()
方法正在线程中运行,并将继续获取下一个传入请求。如果我写这篇文章,我就不会使用HttpListener的实例变量。例如,在ListenAsynchronously方法中创建一个新的并将其传递到state对象中
public class HttpListenerCallbackState
{
private readonly HttpListener _listener;
private readonly AutoResetEvent _listenForNextRequest;
public HttpListenerCallbackState(HttpListener listener)
{
if (listener == null) throw new ArgumentNullException("listener");
_listener = listener;
_listenForNextRequest = new AutoResetEvent(false);
}
public HttpListener Listener { get { return _listener; } }
public AutoResetEvent ListenForNextRequest { get { return _listenForNextRequest; } }
}
public class HttpRequestHandler
{
private int requestCounter = 0;
private ManualResetEvent stopEvent = new ManualResetEvent(false);
public void ListenAsynchronously(IEnumerable<string> prefixes)
{
HttpListener listener = new HttpListener();
foreach (string s in prefixes)
{
listener.Prefixes.Add(s);
}
listener.Start();
HttpListenerCallbackState state = new HttpListenerCallbackState(listener);
ThreadPool.QueueUserWorkItem(Listen, state);
}
public void StopListening()
{
stopEvent.Set();
}
private void Listen(object state)
{
HttpListenerCallbackState callbackState = (HttpListenerCallbackState)state;
while (callbackState.Listener.IsListening)
{
callbackState.Listener.BeginGetContext(new AsyncCallback(ListenerCallback), callbackState);
int n = WaitHandle.WaitAny(new WaitHandle[] { callbackState.ListenForNextRequest, stopEvent});
if (n == 1)
{
// stopEvent was signalled
callbackState.Listener.Stop();
break;
}
}
}
private void ListenerCallback(IAsyncResult ar)
{
HttpListenerCallbackState callbackState = (HttpListenerCallbackState)ar.AsyncState;
HttpListenerContext context = null;
int requestNumber = Interlocked.Increment(ref requestCounter);
try
{
context = callbackState.Listener.EndGetContext(ar);
}
catch (Exception ex)
{
return;
}
finally
{
callbackState.ListenForNextRequest.Set();
}
if (context == null) return;
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 (HttpListenerResponse response = context.Response)
{
//response stuff happens here
string responseString = "Ok";
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.LongLength;
response.OutputStream.Write(buffer, 0, buffer.Length);
response.Close();
}
}
catch (Exception e)
{
}
}
}
公共类HttpListenerCallbackState
{
私有只读HttpListener\u listener;
私有只读自动resetEvent _listenForNextRequest;
公共HttpListenerCallbackState(HttpListener侦听器)
{
如果(listener==null)抛出新的ArgumentNullException(“listener”);
_监听器=监听器;
_listenForNextRequest=newautoresetevent(false);
}
公共HttpListener侦听器{get{return}
public AutoResetEvent ListenForNextRequest{get{return\u ListenForNextRequest;}}
}
公共类HttpRequestHandler
{
私有int请求计数器=0;
private ManualResetEvent stopEvent=新的ManualResetEvent(错误);
公共空列表同步(IEnumerable前缀)
{
HttpListener=新的HttpListener();
foreach(前缀中的字符串s)
{
listener.Prefixes.Add(s);
}
listener.Start();
HttpListenerCallbackState=新的HttpListenerCallbackState(侦听器);
QueueUserWorkItem(侦听,状态);
}
公营部门
{
stopEvent.Set();
}
私有void侦听(对象状态)
{
HttpListenerCallbackState callbackState=(HttpListenerCallbackState)状态;
while(callbackState.Listener.IsListening)
{
callbackState.Listener.BeginGetContext(新的AsyncCallback(ListenerCallback),callbackState);
int n=WaitHandle.WaitAny(新的WaitHandle[]{callbackState.ListenForNextRequest,stopEvent});
如果(n==1)
{
//停止事件已发出信号
callbackState.Listener.Stop();
打破
}
}
}
私有void ListenerCallback(IAsyncResult ar)
{
HttpListenerCallbackState callbackState=(HttpListenerCallbackState)ar.AsyncState;
HttpListenerContext上下文=null;
int requestNumber=联锁增量(参考requestCounter);
尝试
{
context=callbackState.Listener.EndGetContext(ar);
}
捕获(例外情况除外)
{
返回;
}
最后
{
callbackState.ListenForNextRequest.Set();
}
if(context==null)返回;
HttpListenerRequest=context.request;
if(request.HasEntityBody)
{
使用(System.IO.StreamReader sr=new System.IO.StreamReader(request.InputStream,request.ContentEncoding))
{
string requestData=sr.ReadToEnd();
//我对请求所做的事情发生在这里
}
}
尝试
{
使用(HttpListenerResponse=context.response)
{
//这里发生了一些反应
字符串responseString=“确定”;
byte[]buffer=Encoding.UTF8.GetBytes(responseString);
response.ContentLength64=buffer.LongLength;
response.OutputStream.Write(buffer,0,buffer.Length);
response.Close();
}
}
捕获(例外e)
{
}
}
}
在不知道调用此回调的是什么、如何使用WaitHandle listenForNextRequest以及ListenAsynchronously执行的是什么方法的情况下,这有点像猜谜游戏。很抱歉,我添加了您应该打印到控制台(或日志到文件,如果您愿意)的代码,并在此处发布一些有用的调试信息。请指定用于运行此代码的操作系统及其版本。这样会更简单的尝试帮助你。。。关于这一点,GiacomoI使用它作为基础,为.NET2.0应用程序中的简单页面提供服务,它的工作原理给我留下了深刻的印象。在我的笔记本电脑上,我能够每秒向一个简单的单线程负载测试脚本发送130-200个请求,同时每秒向该测试脚本的5个实例发送20个请求。在这些测试中,服务器代码占用了我大约12%的CPU。