2011-12-20 6 views
2

MSDN says HttpListener는 http.sys를 기반으로하며 "HTTP.sys는 연결 관리, 대역폭 조절 및 웹 서버 로깅을 제공합니다."HttpListener 스로틀 링?

서버에 대한 최대 연결 수를 제한해야합니다. HttpListener로이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

답변

1

HttpListener를 사용하는 경우 요청/응답 처리를 담당해야합니다. 응용 프로그램에서 HttpListener의 새 인스턴스를 만들려면 접두사를 추가하고 시작을 호출합니다. 코드가 GetContext 또는 BeginGetContext를 호출하여 응용 프로그램 코드가 들어오는 요청에 응답 할 때까지는 시작되지 않습니다.

BeginGetContext (async)를 호출하면 BegingGetContext가 다시 호출 될 때까지 하나의 요청 만 처리합니다. 그래서 자연스럽게 제한됩니다. 네가 그것을 두 번 부른다면 두 개를 다룰 것이다. 연결 시도는 "대기"될 수 있지만 한 번에 하나씩 만 처리됩니다.

0

HttpListener는 보류중인 연결의 내부 대기열을 유지하므로 단순히 "연결을 수락하지 않음"이 도움이되지 않는다면 대기열을 지워야합니다. 스레드 풀 (.NET < = 4.0) 또는 비동기 연결 (4.5+)로 관리 할 수 ​​있습니다.

"스레드 풀 + 대기열"접근 방식의 예는 Grapevine입니다. 내 R & D 지점 Interpspecific에서 보류중인 요청 수를 제한하도록이 기능이 향상되었습니다. HttpListener 대기열을 지우고 대기열이 "가득"경우 500 개의 요청을 거부합니다. RESTServer.c에서 :

private void HandleRequests() 
    { 
     // Immediately accept and handle any requests: 
     while (this.IsListening) 
     { 
      try 
      { 
       var context = this._listener.GetContext(); 
       this.QueueRequest(context); 
      } 
      catch (Exception e) 
      { 
       EventLogger.Log(e); 
      } 
     } 
    } 

    private void QueueRequest(HttpListenerContext context) 
    { 
     lock (this._queue) 
     { 
      if (_queue.Count > MaxPendingRequests) 
      { 
       context.Response.StatusCode = 503; 
       context.Response.OutputStream.Close(); 
       context.Response.Close(); 
       EventLogger.Log(
        String.Format("Request queue max size reached: {0}. Connection refused with 503 error.", 
            MaxPendingRequests)); 
       return; 
      } 

      this._queue.Enqueue(context); 
      this._ready.Set(); 
     } 
    } 

이 MaxPendingRequests에 큐의 연결을 당겨 스레드 + 수를 총 연결 수를 제한합니다. Hanlder 쓰레드는 큐에서 빠져 나온다. (예를 들어, 연습 문제로 남아 있거나, 예를 들어 RESTServer.c를 보라).

비동기 접근 방식 (훨씬 확장 가능하지만 4.5+ 만 사용)을 사용하는 경우 받아 들일 루프와 연결 제한이 다르지만 일반적인 생각은 동일합니다. 즉, HttpListenerContexts를 즉시 수락하고 "too"이면 500을 반환합니다. 바쁜".