0
我使用this example将同步HTTP服务器(使用.NET的HttpListener)转换为异步。它可以工作,但对于我从Google Chrome发出的每个请求,无论是在地址栏中按Enter还是按F5,我都会收到两个请求。第一个是完美的处理,并在浏览器中响应呈现良好。异步HTTP服务器接收虚假请求
然而,第二个请求甚至不应该出现,它有一个空的查询字符串(我的服务器是一个控制台应用程序,所以我看到所有这些使用Console.WriteLine
)。
当服务器是同步的时候,没有发生这种情况,所以当移动到异步模型时,我一定弄错了一些东西。
下面的代码:
using System;
using System.Diagnostics;
using System.Net;
namespace MyWebServer{
internal static class MyHTTPServer {
private static int mPortNumber = 7091;
private static HttpListener mListener;
private static MyCustomHttpHandler mHttpHandler;
//Omitted some auxiliary methods to print stuff to Console,
//like WriteError and WriteRequestHeaderInformation
public static void Main(String[] pArg) {
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
HttpHandler = new MyCustomHttpHandler();
mPortNumber = Convert.ToInt32(pArg[0]);
Console.WriteLine("Starting the HttpListener on port:{0}", mPortNumber);
InitialiseListener();
Console.WriteLine("Listener started on port: {0}, waiting for requests.", mPortNumber);
Console.WriteLine("Listening. Press Enter to stop.");
Console.ReadLine();
if(mListener.IsListening)
mListener.Stop();
}
private static void InitialiseListener() {
try {
mListener = new HttpListener {
AuthenticationSchemes = AuthenticationSchemes.Basic
};
string prefix = string.Format("http://+:{0}/", mPortNumber);
mListener.Prefixes.Add(prefix);
mListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
mListener.Start();
mListener.BeginGetContext(RequestReceived, null);
} catch(Exception ex) {
WriteError(ex.Message);
}
}
private static void RequestReceived(IAsyncResult result) {
var timer = new Stopwatch();
Console.WriteLine("---Request Received----");
timer.Reset();
timer.Start();
//Retrieve context; on error, print message and wait for another request
HttpListenerContext context = null;
try {
context = mListener.EndGetContext(result);
} catch(HttpListenerException e) {
WriteError(e.ToString());
if(mListener.IsListening)
mListener.BeginGetContext(RequestReceived, null);
return;
}
//Process request and send response
mListener.BeginGetContext(RequestReceived, null);
try {
WriteRequestHeaderInformation(context);
CreateResponseDocument(context);
} catch(Exception ex) {
WriteError(ex.Message);
}
Console.WriteLine("----Request processed in {0} milliseconds ----", timer.ElapsedMilliseconds);
}
private static void CreateResponseDocument(HttpListenerContext pHttpListenerContext) {
try {
byte[] htmlOutput = HttpHandler.ProcessRequest(pHttpListenerContext.Request.Url.LocalPath.Replace("/", ""), pHttpListenerContext.Request.Url.Query.Replace("?", ""));
if(htmlOutput != null && pHttpListenerContext.Response.OutputStream.CanWrite) {
pHttpListenerContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
//pHttpListenerContext.Response.ContentType = "image/jpg";
pHttpListenerContext.Response.ContentType = "text/plain";
pHttpListenerContext.Response.OutputStream.Write(htmlOutput, 0, htmlOutput.Length);
}
pHttpListenerContext.Response.Close();
} catch(Exception ex) {
WriteError(ex.Message);
}
}
}
}
在谷歌浏览器中,当你看'开发者工具',在'网络'选项卡下,你看到一个或两个请求发送到您的服务器? –
只有一个,它是第一个。奇怪的... –
此页面将告诉您如何启用一个功能,在您完成在导航栏中键入它们之前预加载页面。如果您停用此功能,问题是否会消失?:http://support.google.com/chrome/bin/answer.py?hl=zh-CN&answer=1385029 – Chris