2012-12-19 3 views
0

this example 다음에 동기 HTTP 서버 (.NET의 HttpListener 사용)를 비동기로 변환했습니다. 작동하지만 Google 크롬에서 발행하는 모든 요청에 ​​대해 주소창에 입력하거나 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

Google 크롬에서 '개발자 도구'를 볼 때 '네트워크'탭에서 하나 또는 두 개의 요청이 표시되는지 확인합니다. 귀하의 서버로 전송 하시겠습니까? –

+0

그냥 하나, 그리고 첫 번째. 이상한 ... –

+1

이 페이지는 네비게이션 바에 입력하기 전에 페이지를 미리로드하는 기능을 사용하는 방법을 보여줍니다. 이 기능을 사용 중지하면 문제가 사라지지 않습니까? http://support.google.com/chrome/bin/answer.py?hl=ko&answer=1385029 – Chris

답변

0

응답 (이 경우에 JPEG 이미지를 표현) 바이트의 단지 무리 인 경우에만 이런 것 같습니다 :

여기에 코드입니다. 대신 주소 표시 줄에 직접 HTTP 요청을 입력하는 경우이 같은 HTML 페이지 ...

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

... 오직 하나 개의 요청이 내 서버에 의해 수신을 엽니 다. (필자는 내 포트와 매개 변수를 익명으로 처리했으며 queryParametersGoHere는 실제로 ?param1=value1&param2=value2 등을 가지고있었습니다.

관련 문제