using System; using System.Collections.Generic; using System.Threading; using System.Net.NetworkInformation; using System.Net; using System.Text; namespace Shared.SimpleControl.Phone { public class AccountSelectServer : FrameLayout { List mEmqServerList; VerticalScrolViewLayout mVerticalScrolViewLayout; Thread readSpeedThead; public AccountSelectServer () { BackgroundColor = SkinStyle.Current.MainColor; } public override void RemoveFromParent () { IsReadSpeed = false; if (readSpeedThead != null) readSpeedThead.Abort (); MainPage.Loading.Hide (); base.RemoveFromParent (); } public void ShowView () { #region 标题 var topView = new FrameLayout () { Y = Application.GetRealHeight (36), Height = Application.GetRealHeight (90), }; AddChidren (topView); var title = new Button () { TextAlignment = TextAlignment.Center, Text = Language.StringByID (R.MyInternationalizationString.SelectServer), TextSize = 19, TextColor = SkinStyle.Current.TextColor1 }; topView.AddChidren (title); var logo = new Button () { Width = Application.GetRealWidth (154), Height = Application.GetRealHeight (90), X = Application.GetRealWidth (486), UnSelectedImagePath = MainPage.LogoString, Gravity = Gravity.CenterVertical, }; topView.AddChidren (logo); var back = new Button () { Height = Application.GetRealHeight (90), Width = Application.GetRealWidth (85), UnSelectedImagePath = "Item/Back.png", Gravity = Gravity.CenterVertical, }; topView.AddChidren (back); back.MouseUpEventHandler += (sender, e) => { UserMiddle.SettingPageView.PageIndex = UserMiddle.SettingPageView.ChildrenCount - 2; }; #endregion var BodyView = new FrameLayout () { Width = LayoutParams.MatchParent, Height = Application.GetRealHeight (Application.DesignHeight - 126 - 60), Y = topView.Bottom, BackgroundColor = SkinStyle.Current.ViewColor, }; AddChidren (BodyView); mVerticalScrolViewLayout = new VerticalScrolViewLayout (); BodyView.AddChidren (mVerticalScrolViewLayout); var TipView = new Button () { Width = LayoutParams.MatchParent, Y = Application.GetRealHeight (Application.DesignHeight - 60), Height = Application.GetRealHeight (60), BackgroundColor = 0xFFFFFFE0, TextSize = 11, //Text = "温馨提示,使用该功能需确保当前网关固件程序支持!", TextID = R.MyInternationalizationString.TipsSelectServer, TextColor = 0xFF1F1F1F, IsMoreLines = true }; AddChidren (TipView); //加载服务器列表 GetServerList (); } void GetServerList () { Application.RunOnMainThread (() => { MainPage.Loading.Start (Language.StringByID (R.MyInternationalizationString.load)); }); System.Threading.Tasks.Task.Run (() => { var requestJson = Newtonsoft.Json.JsonConvert.SerializeObject (new BaseRequestObj () { LoginAccessToken = MainPage.LoginUser.LoginTokenString }); var revertObj = MainPage.RequestHttps ("", requestJson, false, false, API.GetAllRegionEmqServerList); if (revertObj.StateCode.ToUpper () == "SUCCESS") { var responseDataObj = Newtonsoft.Json.JsonConvert.DeserializeObject> (revertObj.ResponseData.ToString ()); Application.RunOnMainThread (() => { ShowServerListView (responseDataObj); }); } else { Application.RunOnMainThread (() => { new Alert (Language.StringByID (R.MyInternationalizationString.Tip), Language.StringByID (R.MyInternationalizationString.FailureToServer), Language.StringByID (R.MyInternationalizationString.Close)).Show (); }); } Application.RunOnMainThread (() => { MainPage.Loading.Hide (); }); }); } void ShowServerListView (List mServerList) { mVerticalScrolViewLayout.RemoveAll (); mEmqServerList = mServerList; if (mServerList == null) return; foreach (var mServerInfo in mServerList) { AddServerView (mServerInfo, mVerticalScrolViewLayout); } //开启检测服务器响应速度线程 StartCheckServerSpeed (); } void AddServerView (EmqServerInfoRes mServerInfo, VerticalScrolViewLayout VerticalScrolViewMiddle) { var rowView = new RowLayout () { Height = Application.GetRealHeight (110), }; rowView.AddTag ("ID", mServerInfo.Id); VerticalScrolViewMiddle.AddChidren (rowView); Button btnRowLine = new Button () { Y = Application.GetRealHeight (107), Height = Application.GetRealHeight (3), BackgroundColor = SkinStyle.Current.Black50Transparent }; rowView.AddChidren (btnRowLine); var btnPoint = new Button () { Width = Application.GetRealWidth (10), Height = Application.GetRealHeight (10), X = Application.GetRealWidth (50), Gravity = Gravity.CenterVertical, UnSelectedImagePath = "Item/Point.png", SelectedImagePath = "Item/Point.png", Visible = !mServerInfo.IsCurrentSelect }; rowView.AddChidren (btnPoint); var btnName = new Button () { Width = Application.GetRealWidth (370), Text = mServerInfo.EmqDomainOrIp, TextAlignment = TextAlignment.CenterLeft, X = Application.GetRealWidth (90), TextColor = SkinStyle.Current.TextColor1, TextSize = 14, }; rowView.AddChidren (btnName); //btnName.MouseUpEventHandler += (ss, ee) => { // //点击切换 //}; Button mSpeedButton = new Button () { X = Application.GetRealWidth (470), Width = Application.GetRealWidth (108), Height = Application.GetRealHeight (40), Gravity = Gravity.CenterRight, //Text = "0ms", TextColor = 0xFF00FF00, TextSize = 12, }; mSpeedButton.AddTag ("ID", mServerInfo.Id); rowView.AddChidren (mSpeedButton); EventHandler eHandler = (sender, e) => { if (mServerInfo.IsCurrentSelect) return; ShowConfirmAlter (mServerInfo.Id); }; rowView.MouseUpEventHandler += eHandler; btnName.MouseUpEventHandler += eHandler; if (mServerInfo.IsCurrentSelect) { Button btnCheck = new Button () { X = Application.GetRealWidth (20), Y = Application.GetRealHeight (25), Width = Application.GetRealWidth (72), Height = Application.GetRealHeight (61), UnSelectedImagePath = "Skin/Check.png", }; rowView.AddChidren (btnCheck); } } bool IsReadSpeed = false; void StartCheckServerSpeed () { IsReadSpeed = true; readSpeedThead = new Thread ((obj) => { while (IsReadSpeed) { try { foreach (var mServerInfo in mEmqServerList) { long mTime = PingServerAddress (mServerInfo.EmqDomainOrIp); Application.RunOnMainThread (() => { System.Console.WriteLine ($"ping:{mServerInfo.EmqDomainOrIp} {mTime}"); UpdateCheckTime (mServerInfo.Id, mTime); }); System.Threading.Thread.Sleep (100); } System.Threading.Thread.Sleep (5000); } catch { } } }) { IsBackground = true}; readSpeedThead.Start (); } /// /// UpdateCheckTime /// /// /// void UpdateCheckTime (string ID, long mTime) { for (int j = 0; j < mVerticalScrolViewLayout.ChildrenCount; j++) { if (mVerticalScrolViewLayout.GetChildren (j).GetType () == typeof (RowLayout)) { RowLayout frameView = (RowLayout)mVerticalScrolViewLayout.GetChildren (j); if (frameView.GetTagByKey ("ID").ToString () == ID) { for (int k = 0; k < frameView.ChildrenCount; k++) { if (frameView.GetChildren (k).GetType () == typeof (Button)) { Button btn = (Button)frameView.GetChildren (k); if (btn.GetTagByKey ("ID") != null && btn.GetTagByKey ("ID").ToString () == ID) { UpdateCheckTimeWithButton (btn, mTime); } } } } } } } /// /// UpdateCheckTimeWithButton /// /// /// void UpdateCheckTimeWithButton (Button mButton, long mTime) { if (mTime > 1000) { if (mTime >= 2000) { mButton.Text = ">2s"; } else { mButton.Text = mTime + "ms"; } //mButton.Text = ">1s"; mButton.TextColor = 0xFFFF0000; } else { mButton.Text = mTime + "ms"; if (mTime < 200) { mButton.TextColor = 0xFF00FF00; } else { mButton.TextColor = 0xFFFFA500; } } } /// /// HTTP请求响应方法 /// /// /// static long PingServerAddressIos (string serverAddress) { string mAddress = "http://" + serverAddress + ":18083"; try { //1. 创建httpWebRequest对象 var webRequest = (HttpWebRequest)WebRequest.Create (new Uri (mAddress)); webRequest.Timeout = 2000; var dateTime = DateTime.Now; using (var response = (HttpWebResponse)webRequest.GetResponse ()) { return (long)(DateTime.Now - dateTime).TotalMilliseconds; } } catch (Exception ex) { System.Console.WriteLine ($"PingServerAddressIos catch:{ex.ToString ()}"); } return 2000; } /// /// Ping 方法 /// /// /// static long PingServerAddressAndroid (string serverAddress) { long mRoundtripTime = 2000; try { Ping pingSender = new Ping (); byte [] buffer = Encoding.ASCII.GetBytes (string.Empty); PingReply reply = pingSender.Send (serverAddress, 2000, buffer); if (reply.Status == IPStatus.Success) { Console.WriteLine ("Address: {0}", reply.Address.ToString ()); mRoundtripTime = reply.RoundtripTime; } } catch (Exception ex) { System.Console.WriteLine ($"Ping catch:{ex.ToString ()}"); } return mRoundtripTime; } /// /// 检测服务器响应速度 /// /// /// static long PingServerAddress (string serverAddress) { #if __IOS__ return PingServerAddressIos (serverAddress); #else return PingServerAddressAndroid (serverAddress); #endif } /// /// 切换到该服务器 /// /// void ShowConfirmAlter (string mEmqServerId) { //是否选择该服务器为远程连接默认服务器? var alert = new Alert ("", Language.StringByID (R.MyInternationalizationString.IfConfirmSelectEmqRegion), Language.StringByID (R.MyInternationalizationString.Cancel), Language.StringByID (R.MyInternationalizationString.Confrim)); alert.Show (); alert.ResultEventHandler += (sender1, e1) => { if (e1) { ConfirmSelectEmqRegion (mEmqServerId); } }; } /// /// 选择切换该服务器 /// /// void ConfirmSelectEmqRegion (string mEmqServerId) { Application.RunOnMainThread (() => { MainPage.Loading.Start (Language.StringByID (R.MyInternationalizationString.Send)); }); System.Threading.Tasks.Task.Run (() => { var mConfirmSelectEmqRegionRequestObj = new ConfirmSelectEmqRegionRequestObj () { LoginAccessToken = MainPage.LoginUser.LoginTokenString, EmqServerId = mEmqServerId }; var requestJson = Newtonsoft.Json.JsonConvert.SerializeObject (mConfirmSelectEmqRegionRequestObj); var revertObj = MainPage.RequestHttps ("", requestJson, false, false, API.ConfirmSelectEmqRegion); if (revertObj.StateCode.ToUpper () == "SUCCESS") { MainPage.LoginUser.EmqServerId = mEmqServerId; //切换成功,断开远程 重新连接一次远程 if (CommonPage.IsRemote) { SmartHome.MqttCommon.DisConnectRemoteMqttClient ("SelectEmqRegionSuccess"); } Application.RunOnMainThread (() => { //提示选择切换服务器成功,请重启网关! new Alert ("", Language.StringByID (R.MyInternationalizationString.SelectEmqRegionSuccess), Language.StringByID (R.MyInternationalizationString.Close)).Show (); //关闭页面 UserMiddle.SettingPageView.PageIndex = UserMiddle.SettingPageView.ChildrenCount - 2; }); } else { Application.RunOnMainThread (() => { //提示选择切换失败 new Alert ("", Language.StringByID (R.MyInternationalizationString.SelectEmqRegionFail), Language.StringByID (R.MyInternationalizationString.Close)).Show (); }); } Application.RunOnMainThread (() => { MainPage.Loading.Hide (); }); }); } /// /// 判断是否需要自动选择服务器 /// /// public static void CheckIfAutoSelectServer (string mEmqServerId) { if (string.IsNullOrEmpty (mEmqServerId)) { System.Console.WriteLine ($"ConfirmSelectEmqRegion"); GetServerListAndAutoSelect (); } } /// /// 获取服务器列表,并且切换选择到响应速度最快的服务器 /// static void GetServerListAndAutoSelect () { System.Threading.Tasks.Task.Run (() => { //1.获取服务器列表 var requestJson = Newtonsoft.Json.JsonConvert.SerializeObject (new BaseRequestObj () { LoginAccessToken = MainPage.LoginUser.LoginTokenString }); var revertObj = MainPage.RequestHttps ("", requestJson, false, false, API.GetAllRegionEmqServerList); if (revertObj.StateCode.ToUpper () == "SUCCESS") { var mList = Newtonsoft.Json.JsonConvert.DeserializeObject> (revertObj.ResponseData.ToString ()); //2.服务器列表数2个以上 if (mList != null && mList.Count > 1) { //int mCount = 0; string MinDelayEmqServerId = ""; long mPingTime = 3000; bool isAlreadySelected = false; foreach (var mServerInfo in mList) { if (mServerInfo.IsCurrentSelect) { isAlreadySelected = true; continue; } long mTime = PingServerAddress (mServerInfo.EmqDomainOrIp); if (mTime < mPingTime) { mPingTime = mTime; MinDelayEmqServerId = mServerInfo.Id; } System.Threading.Thread.Sleep (100); } //3.所有服务器都没被选择过,才调用选择切换接口 if (!isAlreadySelected) { var mConfirmSelectEmqRegionRequestObj = new ConfirmSelectEmqRegionRequestObj () { LoginAccessToken = MainPage.LoginUser.LoginTokenString, EmqServerId = MinDelayEmqServerId }; var requestJson2 = Newtonsoft.Json.JsonConvert.SerializeObject (mConfirmSelectEmqRegionRequestObj); var revertObj2 = MainPage.RequestHttps ("", requestJson2, false, false, API.ConfirmSelectEmqRegion); if (revertObj2.StateCode.ToUpper () == "SUCCESS") { MainPage.LoginUser.EmqServerId = MinDelayEmqServerId; //4.切换成功,断开远程 重新连接一次远程 if (CommonPage.IsRemote) { SmartHome.MqttCommon.DisConnectRemoteMqttClient ("SelectEmqRegionSuccess"); } } } } } }); } } }