2011-12-20 64 views
2

MSDN says HttpListener基於http.sys,「HTTP.sys提供連接管理,帶寬限制和Web服務器日誌記錄」。HttpListener限制?

我需要限制連接到服務器的最大數量。用HttpListener做這件事的最好方法是什麼?

回答

1

如果您使用HttpListener,這意味着您負責提供請求/響應處理。如果您要在應用程序中創建HttpListener的新實例,請添加一個前綴並調用Start,直到您的代碼調用GetContext或BeginGetContext,您的應用程序代碼纔會響應傳入的請求。

如果您調用BeginGetContext(異步),它將只處理一個請求,直到再次調用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+),則接受循環和連接限制將會有所不同,但總體思路是相同的:立即接受HttpListenerContext並返回500,如果您也是「太忙」。