2012-12-19 73 views
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); 
      } 
     }  
    } 
} 
+1

在谷歌浏览器中,当你看'开发者工具',在'网络'选项卡下,你看到一个或两个请求发送到您的服务器? –

+0

只有一个,它是第一个。奇怪的... –

+1

此页面将告诉您如何启用一个功能,在您完成在导航栏中键入它们之前预加载页面。如果您停用此功能,问题是否会消失?:http://support.google.com/chrome/bin/answer.py?hl=zh-CN&answer=1385029 – Chris

回答

0

看来,出现这种情况只有在响应只是一堆字节(表示在这种情况下,JPEG图像)的。如果不是直接在地址栏中输入http请求我打开一个HTML页面是这样的...

<html> 
    <head/> 
     <body> 
      <img src="http://localhost:serverPort/queryParametersGoHere" /> 
     </body> 
</html> 

...唯一由我的服务器收到一个请求。 (我匿名了我的端口和参数;它说queryParametersGoHere,我实际上有?param1=value1&param2=value2