索引:html
目錄索引json
1、說明數組
1) 這個類 是我 在真實項目中,優化解決真實問題 時,不參考第三方代碼,徹底由本身查閱MSDN官方文檔 , 完成的一個真實生產環境中使用的功能類閉包
2) 讀者在使用此類時,請尊重原創,在代碼中加上原創註釋:// Author -- Meng.NET (cnblogs.com) ,同時歡迎 二次改進、二次創做 以共同進步app
3) 此代碼以【面向對象】、【C#閉包】、【異步回調】、【超時】、【等待】、【自動重試】方式實現及完成,且能夠配置擴展異步
2、代碼ide
廢話很少說,上乾貨,代碼以下:優化
1 /// <summary> 2 /// 異步 Http 3 /// </summary> 4 public class Remoter 5 { 6 /* 7 * LM,2016/08/18 8 * C#閉包化,異步化,Web操做 9 * 以便支持POS多接口多操做同時使用 10 */ 11 12 /// <summary> 13 /// 請求地址 14 /// </summary> 15 public string URL { get; set; } 16 17 /// <summary> 18 /// 請求方式 19 /// </summary> 20 public string RequestMethod { get; set; } 21 22 /// <summary> 23 /// 請求數據 24 /// </summary> 25 public string JsonContent { get; set; } 26 27 // 28 private byte[] Buffer { get; set; } 29 private Stream RequestStream { get; set; } 30 private HttpWebRequest Request { get; set; } 31 private bool ResponseFlag { get; set; } 32 private string Result { get; set; } 33 private bool TimeoutFlag { get; set; } 34 private int TimeoutTime { get; set; } 35 private bool RetryFlag { get; set; } 36 private int RetryCount { get; set; } 37 private int WaitSleep { get; set; } 38 private int TrySleep { get; set; } 39 40 // 初始化 41 public Remoter() 42 { 43 // 44 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3; 45 ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) => true); 46 47 // 48 this.URL = string.Empty; 49 this.Request = default(HttpWebRequest); 50 this.JsonContent = string.Empty; 51 this.Buffer = default(byte[]); 52 this.RequestStream = default(Stream); 53 this.ResponseFlag = false; 54 this.Result = string.Empty; 55 this.TimeoutFlag = false; 56 this.TimeoutTime = 10 * 1000; 57 this.RetryFlag = false; 58 this.RetryCount = 3; 59 this.WaitSleep = 10; 60 this.RequestMethod = "POST"; 61 this.TrySleep = 2000; 62 } 63 64 /// <summary> 65 /// 獲取響應數據 66 /// </summary> 67 public string GetRemoteData() 68 { 69 // 70 if(string.IsNullOrWhiteSpace(this.URL)) 71 { 72 throw new Exception("HttpAsync.URL,未賦值!"); 73 } 74 75 // 76 RemoteNew(SetResult); 77 78 // 79 var timeNum = 0; 80 while (true) 81 { 82 if (ResponseFlag) 83 { 84 break; 85 } 86 if (TimeoutFlag) 87 { 88 throw new Exception(string.Format("請求超時!超時時間:{0}S", TimeoutTime / 1000)); 89 } 90 timeNum += WaitSleep; 91 if (timeNum >= TimeoutTime) 92 { 93 TimeoutFlag = true; 94 } 95 Thread.Sleep(WaitSleep); 96 } 97 98 // 99 return Result; 100 } 101 102 // 103 private void RemoteNew(Action<Remoter, string> action) 104 { 105 // 106 var reNum = 0; 107 for (var i = 0; i < this.RetryCount; i++) 108 { 109 try 110 { 111 // 112 var uri = URL; 113 114 // 115 this.Request = WebRequest.Create(uri) as HttpWebRequest; 116 this.Request.KeepAlive = false; 117 this.Request.Method = this.RequestMethod; 118 this.Request.Credentials = CredentialCache.DefaultCredentials; 119 if (this.RequestMethod.Equals("POST", StringComparison.OrdinalIgnoreCase)) 120 { 121 this.Buffer = Encoding.UTF8.GetBytes(this.JsonContent); 122 this.Request.ContentLength = this.Buffer.Length; 123 this.Request.ContentType = "application/json"; 124 this.RequestStream = this.Request.GetRequestStream(); 125 this.RequestStream.Write(this.Buffer, 0, this.Buffer.Length); 126 this.RequestStream.Close(); 127 } 128 129 // 130 this.Request.BeginGetResponse((arr) => 131 { 132 // 133 var state = arr.AsyncState as Remoter; 134 // 135 var response = state.Request.EndGetResponse(arr) as HttpWebResponse; 136 var respStream = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("UTF-8")); 137 action(state, respStream.ReadToEnd()); 138 respStream.Close(); 139 response.Close(); 140 }, this); 141 // 142 break; 143 } 144 catch (Exception ex) 145 { 146 Thread.Sleep(this.TrySleep); 147 reNum++; 148 if (reNum == this.RetryCount) 149 { 150 throw new Exception(string.Format("重試失敗!重試次數:{0}次,失敗緣由:{1}", this.RetryCount, ex.Message)); 151 } 152 continue; 153 } 154 } 155 } 156 private void SetResult(Remoter state, string jsonData) 157 { 158 if (!string.IsNullOrWhiteSpace(jsonData)) 159 { 160 state.Result = jsonData; 161 state.ResponseFlag = true; 162 } 163 } 164 }
使用方式:this
GET: spa
1 var remoter = new Remoter(); 2 remoter.RequestMethod = "GET"; 3 remoter.URL = "這裏是你要請求的URL"; 4 var response = remoter.GetRemoteData();
POST:
1 var remoter = new Remoter(); 2 remoter.RequestMethod = "POST"; 3 remoter.URL = "你要請求的URL"; 4 remoter.JsonContent = "你要想URL發送的JSON數據"; 5 var response = remoter.GetRemoteData();
3、代碼解析
public Remoter() 初始化本類,可配置到 App.config/Web.config 中
1 // 2 this.URL = string.Empty; 3 this.Request = default(HttpWebRequest); 4 this.JsonContent = string.Empty; 5 this.Buffer = default(byte[]); 6 this.RequestStream = default(Stream); 7 this.ResponseFlag = false; 8 this.Result = string.Empty; 9 this.TimeoutFlag = false; 10 this.TimeoutTime = 10 * 1000; 11 this.RetryFlag = false; 12 this.RetryCount = 3; 13 this.WaitSleep = 10; 14 this.RequestMethod = "POST"; 15 this.TrySleep = 2000;
public string URL 要請求的地址
public string RequestMethod HTTP 動詞
public string JsonContent POST 請求時,發送的json數據
private byte[] Buffer 設置請求流的byte數組
private Stream RequestStream 請求流
private HttpWebRequest Request HTTP請求對象
private bool ResponseFlag 與請求對應的響應是否成功標識
private string Result 回調狀態保持對象,保存響應結果用
private bool TimeoutFlag 總超時時間是否超時標識
private int TimeoutTime 總超時時間(包含若干次重試),默認10s
private int RetryCount 總URL調用(失敗)自動重試次數,默認3次
private int WaitSleep 主線程,仿Ajax回調等待時間,默認10ms
private int TrySleep 每次請求地址失敗後,重試時間間隔,默認2s
public string GetRemoteData() 解析:
1 // 2 var timeNum = 0; 3 while (true) 4 { 5 if (ResponseFlag) 6 { 7 break; 8 } 9 if (TimeoutFlag) 10 { 11 throw new Exception(string.Format("請求超時!超時時間:{0}S", TimeoutTime / 1000)); 12 } 13 timeNum += WaitSleep; 14 if (timeNum >= TimeoutTime) 15 { 16 TimeoutFlag = true; 17 } 18 Thread.Sleep(WaitSleep); 19 }
private void RemoteNew(Action<Remoter, string> action) 解析:
1 private void RemoteNew(Action<Remoter, string> action) 2 { 3 // 4 var reNum = 0; 5 for (var i = 0; i < this.RetryCount; i++) 6 { 7 try 8 { 9 // 此處省略 10 //... ... 11 12 // 13 break; 14 } 15 catch (Exception ex) 16 { 17 Thread.Sleep(this.TrySleep); 18 reNum++; 19 if (reNum == this.RetryCount) 20 { 21 throw new Exception(string.Format("重試失敗!重試次數:{0}次,失敗緣由:{1}", this.RetryCount, ex.Message)); 22 } 23 continue; 24 } 25 } 26 }
1 // 2 this.Request.BeginGetResponse((arr) => 3 { 4 // 5 var state = arr.AsyncState as Remoter; 6 // 7 var response = state.Request.EndGetResponse(arr) as HttpWebResponse; 8 var respStream = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("UTF-8")); 9 action(state, respStream.ReadToEnd()); 10 respStream.Close(); 11 response.Close(); 12 }, this);
private void SetResult(Remoter state, string jsonData) 解析:
1 state.Result = jsonData; 2 state.ResponseFlag = true;
4、計劃中的開源項目...
計劃後續會將生產中解決問題的諸多地方聚集成一個項目【Meng.Net.dll】並開源至GitHub上,歡迎交流,共同提升~~
至於本文所講的類會在哪一個命名空間中,還沒想好,項目的總體結構及主打方向,敬請期待......
蒙
2016-09-24 22:37 週六