1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.IO; 7 using System.Linq; 8 using System.Net; 9 using System.Text; 10 using System.Threading; 11 using System.Threading.Tasks; 12 using System.Windows.Forms; 13 using System.Text.RegularExpressions; 14 using Util; 15 16 namespace App 17 { 18 public partial class FormChooseSite : Form 19 { 20 private SynchronizationContext syncContext = null; 21 private System.Windows.Forms.Timer autoEnterTimer = null; 22 23 private RadioButton checkedRadioButton = null; 24 private bool autoChoosedSite = false; 25 26 private const string ServiceSitesConfigDate = "2016-7-18"; 27 private string serviceSitesXmlFile = null; 28 29 public FormChooseSite() 30 { 31 InitializeComponent(); 32 syncContext = SynchronizationContext.Current; 33 serviceSitesXmlFile = GetServiceSitesXmlFilePath(); 34 35 autoEnterTimer = new System.Windows.Forms.Timer(); 36 autoEnterTimer.Interval = 1000; 37 autoEnterTimer.Tag = 3; 38 autoEnterTimer.Tick += (s, e) => 39 { 40 int remainTimes = Convert.ToInt32(autoEnterTimer.Tag); 41 if (remainTimes == -1) 42 { 43 autoEnterTimer.Enabled = false; 44 return; 45 } 46 47 var choosedSite = checkedRadioButton.Tag as ServiceSite; 48 btnEnter.Text = string.Format("使用系统推荐的站点【{0}】进入系统 ({1})", choosedSite.SiteName, --remainTimes); 49 autoEnterTimer.Tag = remainTimes; 50 if (remainTimes <= 0) 51 { 52 autoEnterTimer.Enabled = false; 53 btnEnter.PerformClick(); 54 } 55 }; 56 } 57 58 59 60 private void FrmChooseSite_Load(object sender, EventArgs e) 61 { 62 btnEnter.Enabled = false; 63 layoutPanSites.Enabled = false; 64 this.Cursor = Cursors.WaitCursor; 65 66 Task.Factory.StartNew(() => 67 { 68 var serviceSiteList = GetServiceSiteList(); 69 70 List<Task> taskList = new List<Task>(); 71 string currentIp = null; 72 73 taskList.Add(Task.Factory.StartNew(() => 74 { 75 currentIp = GetCurrentIpInfo(); 76 syncContext.Post((o) => { labIpInfo.Text = currentIp; }, null); 77 })); 78 79 foreach (var item in serviceSiteList) 80 { 81 taskList.Add(Task.Factory.StartNew(() => 82 { 83 item.TestAndLoadConnectionData(5, 2); 84 syncContext.Post(LoadServiceSiteInfo, item); 85 })); 86 } 87 88 Task.WaitAll(taskList.ToArray()); 89 90 91 syncContext.Post((o) => 92 { 93 //var sites = o as List<ServiceSite>; 94 //foreach (var item in serviceSiteList) 95 //{ 96 // LoadServiceSiteInfo(item); 97 //} 98 99 layoutPanSites.Controls.Remove(labLoading); 100 btnEnter.Enabled = true; 101 layoutPanSites.Enabled = true; 102 this.Cursor = Cursors.Default; 103 104 }, serviceSiteList); 105 106 var bestServiceSite = GetBestServiceSite(serviceSiteList, currentIp); 107 108 syncContext.Post((o) => 109 { 110 var site = o as ServiceSite; 111 var rdbtn = layoutPanSites.Controls.Cast<Control>().FirstOrDefault(c => c.Tag.Equals(site)) as RadioButton; 112 if (rdbtn != null) 113 { 114 autoChoosedSite = true; 115 rdbtn.Checked = true; 116 autoChoosedSite = false; 117 this.Text += string.Format(" - [ 系统推荐站点:{0} ]", site.SiteName); 118 119 autoEnterTimer.Enabled = true; 120 } 121 }, bestServiceSite); 122 123 }); 124 } 125 126 private string GetServiceSitesXmlFilePath() 127 { 128 if (!File.Exists(serviceSitesXmlFile)) 129 { 130 string xmlFile = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Bin\\"; 131 if (!Directory.Exists(xmlFile)) 132 { 133 Directory.CreateDirectory(xmlFile); 134 } 135 serviceSitesXmlFile = xmlFile + "ServiceSites.xml"; 136 } 137 return serviceSitesXmlFile; 138 } 139 140 private void LoadServiceSiteInfo(object state) 141 { 142 var serviceSite = state as ServiceSite; 143 var rdBtn = new MyStyleRedioButton(); 144 rdBtn.Name = "rdBtn" + layoutPanSites.Controls.Count.ToString(); 145 rdBtn.Tag = serviceSite; 146 rdBtn.Text = string.Format("{0}:{1}(平均耗时:{2}ms;丢包率:{3})", serviceSite.SiteName, serviceSite.ConnectionStatus ? GetEnumDescription(serviceSite.ConnectionSpeed) : "失败", serviceSite.AvgSpeed, serviceSite.PacketLossRate); 147 rdBtn.AutoSize = false; 148 rdBtn.TextAlign = ContentAlignment.MiddleLeft; 149 rdBtn.Width = 280; 150 rdBtn.Height = 30; 151 rdBtn.Padding = new System.Windows.Forms.Padding() { Left = 5 }; 152 rdBtn.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5); 153 //rdBtn.BackGroundColor = Color.Purple; //ColorTranslator.FromHtml("#9F79EE"); 154 rdBtn.ForeColor = Color.White; 155 if (serviceSite.ConnectionStatus) 156 { 157 if (serviceSite.ConnectionSpeed >= ServiceSite.ConnectionSpeeds.Normal) 158 { 159 rdBtn.BackGroundColor = Color.Purple; 160 } 161 else 162 { 163 rdBtn.BackGroundColor = Color.Orange; 164 } 165 } 166 else 167 { 168 rdBtn.BackGroundColor = Color.Red; 169 } 170 rdBtn.CheckedChanged += rdBtn_CheckedChanged; 171 layoutPanSites.Controls.Add(rdBtn); 172 layoutPanSites.Controls.SetChildIndex(rdBtn, layoutPanSites.Controls.Count - 2); 173 } 174 175 private void rdBtn_CheckedChanged(object sender, EventArgs e) 176 { 177 var rdBtn = sender as RadioButton; 178 if (rdBtn.Checked) 179 { 180 var choosedSite = rdBtn.Tag as ServiceSite; 181 checkedRadioButton = rdBtn; 182 if (autoChoosedSite) 183 { 184 btnEnter.Text = string.Format("使用系统推荐的站点【{0}】进入系统 (3)", choosedSite.SiteName); 185 } 186 else 187 { 188 btnEnter.Text = string.Format("使用当前选择的站点【{0}】进入系统", choosedSite.SiteName); 189 autoEnterTimer.Tag = -1; 190 } 191 } 192 } 193 194 private string GetEnumDescription(Enum enumValue) 195 { 196 string str = enumValue.ToString(); 197 System.Reflection.FieldInfo field = enumValue.GetType().GetField(str); 198 object[] objs = field.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false); 199 if (objs == null || objs.Length == 0) return str; 200 System.ComponentModel.DescriptionAttribute da = (System.ComponentModel.DescriptionAttribute)objs[0]; 201 return da.Description; 202 } 203 204 private List<ServiceSite> GetServiceSiteList() 205 { 206 207 InitializeConfigInfo: 208 209 if (!File.Exists(serviceSitesXmlFile)) 210 { 211 SaveServiceSiteList(); 212 } 213 214 DataSet serviceSiteDs = new DataSet(); 215 serviceSiteDs.ReadXml(serviceSitesXmlFile); 216 217 string serviceSitesConfigDateFromXml = (serviceSiteDs.ExtendedProperties["ConfigDate"] ?? "").ToString(); 218 219 if (!serviceSitesConfigDateFromXml.Equals(ServiceSitesConfigDate, StringComparison.OrdinalIgnoreCase))//配置日期不相同,则需重新生成 220 { 221 File.Delete(serviceSitesXmlFile); 222 goto InitializeConfigInfo; 223 } 224 225 List<ServiceSite> serviceSiteList = new List<ServiceSite>(); 226 if (serviceSiteDs.Tables.Contains("ServiceSite")) 227 { 228 foreach (DataRow row in serviceSiteDs.Tables["ServiceSite"].Rows) 229 { 230 serviceSiteList.Add(new ServiceSite(row["SiteName"].ToString(), row["IpAddress"].ToString(), Convert.ToInt32(row["Port"]), 231 row["Region"].ToString(), row["NetProvider"].ToString())); 232 } 233 } 234 return serviceSiteList; 235 } 236 237 private void SaveServiceSiteList() 238 { 239 240 DataSet serviceSiteDs = new DataSet("ServiceSiteConfig"); 241 serviceSiteDs.ExtendedProperties.Add("ConfigDate", ServiceSitesConfigDate); 242 243 DataTable dt = new DataTable("ServiceSite"); 244 dt.Columns.Add("SiteName", typeof(string)); 245 dt.Columns.Add("IpAddress", typeof(string)); 246 dt.Columns.Add("Port", typeof(int)); 247 dt.Columns.Add("Region", typeof(string)); 248 dt.Columns.Add("NetProvider", typeof(string)); 249 250 serviceSiteDs.Tables.Add(dt); 251 252 dt.Rows.Add("深圳电信1", "xxx.xxx.xxx.xxx", 8080, "深圳", "电信"); 253 dt.Rows.Add("深圳电信2", "xxx.xxx.xxx.xxx", 8080, "深圳", "电信"); 254 dt.Rows.Add("深圳多网", "xxx.xxx.xxx.xxx", 8080, "深圳", "多网"); 255 dt.Rows.Add("深圳联通", "xxx.xxx.xxx.xxx", 8080, "深圳", "联通");258 259 serviceSiteDs.WriteXml(serviceSitesXmlFile, XmlWriteMode.WriteSchema); 260 } 261 262 private string GetCurrentIpInfo() 263 { 264 using (WebClient client = new WebClient()) 265 { 266 string url = "http://1212.ip138.com/ic.asp"; 267 string content = client.DownloadString(url); 268 Regex rg = new Regex("(?<=<center>).+(?=</center>)", RegexOptions.IgnoreCase); 269 return rg.Match(content).Value; 270 } 271 } 272 273 private ServiceSite GetBestServiceSite(List<ServiceSite> siteList, string currentIp) 274 { 275 var okSites = siteList.Where(s => s.ConnectionStatus);//获取端口连接正常的站点列表 276 277 //var sameNetProviderSites = okSites.Where(s => currentIp.IndexOf(s.NetProvider, StringComparison.OrdinalIgnoreCase) >= 0);//获取同属一个网络运营商的站点列表 278 //if (sameNetProviderSites == null || sameNetProviderSites.Count() <= 0) 279 //{ 280 // sameNetProviderSites = okSites; 281 //} 282 283 //var sameRegionSites = sameNetProviderSites.Where(s => currentIp.IndexOf(s.Region, StringComparison.OrdinalIgnoreCase) >= 0);//获取同属于一个城市(地区)的站点列表 284 //if (sameRegionSites == null || sameRegionSites.Count() <= 0) 285 //{ 286 // sameRegionSites = sameNetProviderSites; 287 //} 288 289 return okSites.OrderBy(s => s.AvgSpeed).FirstOrDefault();//返回平均速度最高的一个站点作为最佳站点 290 } 291 292 293 private void SiteSetting() 294 { 295 var choosedSite = checkedRadioButton.Tag as ServiceSite; 296 //Program.AppWebSrvHost = string.Format("{0}:{1}", choosedSite.IpAddress, choosedSite.Port); 297 } 298 299 private void btnEnter_Click(object sender, EventArgs e) 300 { 301 SiteSetting(); 302 this.DialogResult = DialogResult.OK; 303 } 304 } 305 }
闲着就高了这个玩意,大家可以看看,这个是根据本地IP测试连接其他站点,选择最优站点的一段代码,WEB端我不会写HTML就没搞,不过后端都差不多,可以写成接口的方式调用。