2017年1月25日

壓測程式使用HttpWebRequest

有時候我們需要自行寫一支Web的壓測程式或是點擊率程式(誤),那需要用到甚麼物件來達到這目標呢?候選就是HttpWebRequest


目標


可以輸入Request的URL,並設定次數,有必要時可選是否休息再送出,或是加入字串,最後算出費時
image
[名詞解釋]
  • Thread (執行緒)- 一段程式是在主執行緒執行,如果有分開執行程式要同時執行,這時就可另外建立一執行緒來執行,因UI更新通常有主執行緒在處理,將讀取資料使用另一執行緒去讀取,可避免畫面被凍結。
  • Asynchronous(同步) - 非同步很容易誤解非同是執行,這是完全相反意思,正確的意思是非連續執行,因此非同步呼叫會以另一執行緒去執行,執行完成後會呼叫一個完成程序,完成程序可能是將回傳的資料更新到畫面,或是彈跳完成訊息。
  • Synchronous(同步) – 舊式非同步的相反,意思是呼叫的程式和原執行緒是連續執行,也就是所呼叫的程式必須完成後才會執行後面的程式,因此如果有去呼叫一段讀資料程序,畫面會凍結到資料讀完為止。
  • Blocking(阻塞) - 一般指的是使用者介面被凍結無法回應,或是一段程式碼防止另一段程式碼執行,MessageBox 在 .NET, ShowDialog()執行時,畫面要等到對話框結束才能繼續執行
  • Request(要求) – request表示呼叫一個網址並帶有一些參數,瀏覽器尋訪一個網站也是用Request。
  • Response(回應) - 便是request後所回應的資料,遠端Server會回應Request,回應內容可能是Html網頁,或是XML,或是JSON字串表示的物件(可以轉成.NET物件)。

     


實作



這邊是使用Synchronous呼叫
首先先建立一個Request Method
 
private void RequestSomePage() 
{ 
    string url = txtUrl.Text;   //設定URL       
    if (chkAppendQuertString.Checked) 
    { 
        url +=  GetQueryString(); //加入字串 
    } 
    _req =(HttpWebRequest)HttpWebRequest.Create( url); //建立HttpWebRequest 
    _req.Date = DateTime.Now; 
    
    using (WebResponse wr = _req.GetResponse()) 
    { 
        //在這裡對接收到的頁面內容進行處理 
        //這裡不做任何事 
    } 
    _req.Abort(); 
    
} 


這裡有個Method組時間當成參數
 
private string GetQueryString() 
{ 
    string ret; 
     DateTime nowDt = DateTime.Now; 
     ret = nowDt.Year.ToString() + nowDt.Month.ToString("00") + nowDt.Day.ToString("00") 
           + nowDt.Hour.ToString("00") + nowDt.Minute.ToString("00") + nowDt.Second.ToString("00") + 
           nowDt.Millisecond.ToString(); 
    return ret= "?a=" +ret; 
}


最後按下按鈕呼叫RequestSomePage
 
private void button1_Click(object sender, EventArgs e) 
{
    var watch = Stopwatch.StartNew();//計數用 
    
    int maxCount; //尋訪最大數 
    
    maxCount = int.Parse(txtCounts.Text);
    button1.Enabled = false;//不可再重複送出 
    
    for (int i = 0; i < maxCount; i++) 
    
    { 
        
        RequestSomePage();
        if (chkSleep.Checked) 
            
    System.Threading.Thread.Sleep(8000); //休息8秒 
    
    }
    MessageBox.Show("Finished"); 
    
    button1.Enabled = true;
    watch.Stop();//Stop計數 
    
    var elapsedMs = watch.ElapsedMilliseconds; 
    
    TimeSpan ts = watch.Elapsed; 
    
    textBox1.Text = ts.ToString("mm\\:ss\\.ff");//顯示費時 

 }

測試

我們加入一個空白ASP.NET專案,新增一個Web表單,命名為Default.aspx
image
拉一個Label,前面寫著Counts:
<body>
    <form id="form1" runat="server">
    <div>
   
        Counts:&nbsp;
        <asp:Label ID="lblCounts" runat="server" Text="0"></asp:Label>
   
    </div>
    </form>
</body>

並在增加一個Global.aspx
image
並在Application_Start加入Application變數PageRequestCount,並設定為0
 
protected void Application_Start(object sender, EventArgs e) 
{ 
    Application["PageRequestCount"] = 0; 
}

完成後記得要建置專案
接著到控制台-新增移除程式,確定IIS相關設定已打開
image
打開IIS管理員,將WebTest加入Default website
image

打開Default.aspx2的Form_Load填入以下程式
 
protected void Page_Load(object sender, EventArgs e) 

{ 
    
  Application.Lock(); 
    
  Application["PageRequestCount"] = (int)Application["PageRequestCount"]) + 1;
  lblCounts.Text = Application["PageRequestCount"].ToString(); 
    
  Application.UnLock(); 
    

}


建置完成後,在瀏覽器輸入http://localhost/webtest/
不斷的refresh,counts會加1
image
這時可執行我們的壓測程式
image
refresh一下網頁,得到 233+1次,的確呼叫了233次
image

GitHub程式碼:


https://github.com/johnsonkao/HttpRequest

參考:


Handling the HttpWebRequest

沒有留言:

張貼留言