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);
}
}
}
}
Google 크롬에서 '개발자 도구'를 볼 때 '네트워크'탭에서 하나 또는 두 개의 요청이 표시되는지 확인합니다. 귀하의 서버로 전송 하시겠습니까? –
그냥 하나, 그리고 첫 번째. 이상한 ... –
이 페이지는 네비게이션 바에 입력하기 전에 페이지를 미리로드하는 기능을 사용하는 방법을 보여줍니다. 이 기능을 사용 중지하면 문제가 사라지지 않습니까? http://support.google.com/chrome/bin/answer.py?hl=ko&answer=1385029 – Chris