JLChen
2021-01-11 5a5a2b696866f947b6025d26c3302e8ffef46435
Crabtree/SmartHome/UI/SimpleControl/MqttCommon.cs
@@ -11,7 +11,6 @@
using System.Text;
using System.Security.Cryptography;
using System.IO;
using Shared.SimpleControl.Phone;
namespace SmartHome
{
@@ -22,488 +21,482 @@
        /// </summary>
        public static bool IfDEBUG = false;
        /// <summary>
        /// 加密通讯KEY
        /// </summary>
        static string mqttEncryptKey = "";
        static string checkGatewayTopicBase64 = "";
        static RemoteMACInfo CurRemoteMACInfo = null;
        static MqttInfo mMqttInfo = null;
        public static bool IsGatewayOnline = true;
        //static string checkGatewayTopicBase64 = "";
        /// <summary>
        /// 手机标识
        /// 挤下线主题
        /// </summary>
        static Guid currentGuid = Guid.NewGuid ();
        static readonly string PushNotifySqueeze = "/Push/NotifySqueeze";
        ///// <summary>
        ///// 挤下线主题
        ///// </summary>
        //static readonly string TopicToApp = "/Push/NotifySqueeze";
        /// <summary>
        /// 外网的MQTT是否正在连接
        /// 随机Key
        /// </summary>
        /// <summary>
        /// 远程MqttClient
        /// </summary>
        static string RandomKey = "";
        static string GetRandomKey ()
        {
            if (string.IsNullOrEmpty (RandomKey)) {
                //随机2位字符串
                RandomKey = Utlis.CreateRandomString (2);
            }
            return RandomKey;
        }
        /// <summary>
        /// 远程MqttClient
        /// </summary>
        public static IMqttClient RemoteMqttClient = new MqttFactory ().CreateMqttClient ();
        //static bool thisShowTip = true;
        static string mqttRequestParToken = "";
        static MqttCommon ()
        {
            InitMqtt ();
            //InitCheckGateway ();
        }
        /// <summary>
        /// 保活重连和重订阅 线程
        /// </summary>
        /// <returns></returns>
        public static async System.Threading.Tasks.Task InitMqtt ()
        {
            new System.Threading.Thread (async () => {
                while (true) {
                    try {
                        System.Threading.Thread.Sleep (200);
                        if (!CommonPage.IsRemote) continue;
                        if (Control.IsEnterBackground) continue;
                        await StartCloudMqtt ();
                        await CheckingSubscribeTopics ();
                    } catch { }
                }
            }) { IsBackground = true }.Start ();
        }
        public static void InitState ()
        {
            IfNeedReadAllDeviceStatus = true;
            bNeedStartTip = true;
            IsGatewayOnline = false;
            StartCloudMqtt ();
        }
        /// <summary>
        /// 是否订阅成功
        /// </summary>
        static bool isSubscribeTopicSuccess = false;
        /// <summary>
        /// 检查主题是否订阅失败
        /// </summary>
        /// <returns></returns>
        static async Task CheckingSubscribeTopics ()
        {
            if (!remoteIsConnected) {
                return;
            }
            try {
                if (!isSubscribeTopicSuccess) {
                    var topicFilterCommon = new TopicFilter () {
                        Topic = $"/BusGateWayToClient/{CurRemoteMACInfo.macMark}/Common/#",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    };
                    //网关重新登录主题
                    var topicFilterGateWayInfoChange = new TopicFilter () {
                        Topic = $"/BusGateWayToClient/{CurRemoteMACInfo.macMark}/NotifyBusGateWayInfoChange",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    };
                    //挤下线主题
                    var topicFilterNotifySqueeze = new TopicFilter () {
                        Topic = $"/BusGateWayToClient/{mMqttInfo.connEmqClientId}/Push/NotifySqueeze",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    };
                    //网关掉线主题
                    var topicFilterNotifyGateWayOffline = new TopicFilter () {
                        Topic = $"/BusGateWayToClient/{CurRemoteMACInfo.macMark}/NotifyGateWayOffline",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    };
                    var topicFilters = new TopicFilter [] { topicFilterCommon, topicFilterGateWayInfoChange, topicFilterNotifySqueeze, topicFilterNotifyGateWayOffline };
                    var result = await RemoteMqttClient.SubscribeAsync (topicFilters);
                    if (result.Items [0].ResultCode == MQTTnet.Client.Subscribing.MqttClientSubscribeResultCode.GrantedQoS2) {
                        isSubscribeTopicSuccess = true;
                    }
                    ////2020-06-22 通用主题
                    //var topicFilterMacMark = new TopicFilter () {
                    //    Topic = $"/BusGateWayToClient/{CurRemoteMACInfo.macMark}/#",
                    //    QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    //};
                    ////挤下线主题
                    //var topicFilterNotifySqueeze = new TopicFilter () {
                    //    Topic = $"/BusGateWayToClient/{mMqttInfo.connEmqClientId}/Push/NotifySqueeze",
                    //    QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    //};
                    //var topicFilters = new TopicFilter [] { topicFilterMacMark, topicFilterNotifySqueeze };
                    //var result = await RemoteMqttClient.SubscribeAsync (topicFilters);
                    //if (result.Items [0].ResultCode == MQTTnet.Client.Subscribing.MqttClientSubscribeResultCode.GrantedQoS2) {
                    //    isSubscribeTopicSuccess = true;
                    //}
                }
            } catch (Exception ex) {
            }
        }
        /// <summary>
        /// 断开远程Mqtt的链接
        /// </summary>
        public static async System.Threading.Tasks.Task DisConnectRemoteMqttClient (string s = "")
        {
            try {
                if (remoteIsConnected) {
                    remoteIsConnected = false;
                    Utlis.WriteLine ($"============>MqttRemote主动断开_{s}");
                    //await RemoteMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions { }, CancellationToken.None);
                    await RemoteMqttClient.DisconnectAsync ();
                    if (CommonPage.IsRemote) {
                        Utlis.ShowAppLinkStatus (AppLinkStatus.CloudUnlink);
                    }
                    //Utlis.WriteLine ($"============>MqttRemoteDisConnectRemoteMqttClient");
                }
            } catch (Exception e) {
                Utlis.WriteLine ($"============>MqttRemote断开通讯连接出异常:{e.Message}");
            }
        }
        static DateTime dateTime = DateTime.MinValue;
        /// <summary>
        /// 推送标识
        /// </summary>
        static string PushSignStr = System.DateTime.Now.Ticks.ToString ();
        /// <summary>
        /// 断开远程Mqtt的链接
        /// </summary>
        static async System.Threading.Tasks.Task DisConnectRemoteMqttClient (string s = "")
        {
            try {
                if (remoteIsConnected) {
                    remoteIsConnected = false;
                    isSubscribeSuccess = false;
                    Shared.Utlis.WriteLine ($"Remote主动断开_{s}");
                    //await RemoteMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions { }, CancellationToken.None);
                    await RemoteMqttClient.DisconnectAsync ();
                    if (CommonPage.IsRemote) {
                        //不是无网络
                        if (UserConfig.Instance.internetStatus != 0) {
                            Utlis.ShowAppLinkStatus (AppLinkStatus.CloudUnlink);
                        }
                    }
                }
            } catch (Exception e) {
                Shared.Utlis.WriteLine ($"Remote断开通讯连接出异常:{e.Message}");
            }
        }
        /// <summary>
        /// 断开远程Mqtt的链接
        /// </summary>
        static async Task DisConnectRemoteMqttClientWhenStart (string s = "")
        {
            try {
                //if (remoteIsConnected) {
                remoteIsConnected = false;
                isSubscribeSuccess = false;
                Shared.Utlis.WriteLine ($"RemoteStart主动断开_{s}");
                await RemoteMqttClient.DisconnectAsync ();
                //}
            } catch (Exception e) {
                Shared.Utlis.WriteLine ($"RemoteStart断开通讯连接出异常:{e.Message}");
            }
        }
        /// <summary>
        /// 断开mqtt连接
        /// </summary>
        /// <param name="s">断开原因</param>
        /// <param name="reset">是否需要去中心服务器 重新获取参数</param>
        /// <returns></returns>
        public static async Task DisConnectRemote (string s = "", bool reset = true)
        {
            if (reset) {
                bNeedStartTip = true;
                bNeedConnectTip = true;
                CommonConfig.Current.IfGetMqttInfoSuccess = false;
            }
            await DisConnectRemoteMqttClient (s);
        }
        //static DateTime dateTime = DateTime.MinValue;
        /// <summary>
        /// 外网的MQTT是否正在连接
        /// </summary>
        public static bool remoteMqttIsConnecting;
        static bool remoteIsConnected;
        static MqttCommon ()
        {
            InitMqtt ();
        }
        public static bool IsInitMqtt = false;
        ///// <summary>
        ///// 测试
        ///// 定时发送 000E
        ///// </summary>
        ///// <returns></returns>
        //static void InitCheckGateway ()
        //{
        //    new System.Threading.Thread (async () => {
        //        while (true) {
        //            try {
        //                if (!CommonPage.IsRemote) {
        //                    if (GatewayCommon != null) {
        //                        Control.ControlBytesSend (Command.ReadRemark, GatewayCommon.SubnetID, GatewayCommon.DeviceID, new byte [] { });
        //                        Console.WriteLine ("发送000E ");
        //                    }
        //                }
        //                System.Threading.Thread.Sleep (55000);
        //            } catch { }
        //        }
        //    }) { IsBackground = true }.Start ();
        //}
        //static Thread MQTTThread;
        //static void InitMqtt ()
        //{
        //    remoteMqttIsConnecting = false;
        //    if (MQTTThread != null)
        //        MQTTThread.Abort ();
        //    MQTTThread = new System.Threading.Thread (async () => {
        //        while (true) {
        //            try {
        //                System.Threading.Thread.Sleep (200);
        //                //if (!MainPage.LoginUser.IsLogin) {
        //                //    continue;
        //                //}
        //                if (!CommonPage.IsRemote) continue;
        //                await StartCloudMqtt ();
        //                await SubscribeTopics ();
        //            } catch { }
        //        }
        //    }) { IsBackground = true };
        //    MQTTThread.Start ();
        //}
        static void InitMqtt ()
        {
            new System.Threading.Thread (async () => {
                while (true) {
                    try {
                        System.Threading.Thread.Sleep (500);
                        //if (!MainPage.LoginUser.IsLogin) {
                        //    continue;
                        //}
                        if (!CommonPage.IsRemote) continue;
                        if (Control.IsEnterBackground) continue;
                        await StartCloudMqtt ();
                        await SubscribeTopics ();
                    } catch { }
                }
            }) { IsBackground = true }.Start ();
        }
        /// <summary>
        /// 初始化状态
        /// </summary>
        public static void InitState ()
        {
            IfNeedReadAllDeviceStatus = true;
            bNeedStartTip = true;
            bNeedConnectTip = true;
            IsGatewayOnline = false;
            StartCloudMqtt ();
        }
        static bool isSubscribeSuccess;
        static async Task SubscribeTopics ()
        {
            if (remoteIsConnected && !isSubscribeSuccess) {
                try {
                    //var topicFilterPush = new TopicFilter { QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce,
                    //    Topic = $"/BusGateWayToClient/{CommonConfig.Instance.CurRemoteMACInfo.clientId}/Push/NotifySqueeze" };
                    //2020-05-14 订阅主题质量改为0
                    var topicFilterBusGateWayToClient = new MqttTopicFilter () {
                        Topic = $"/BusGateWayToClient/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/#",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                        //QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    };
                    var topicFilterPush2 = new MqttTopicFilter {
                        Topic = $"/BusGateWayToClient/{MainPage.LoginUser.ID}/#",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce,
                        //QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    };
                    Utlis.WriteLine ("开始订阅!");
                    var result = await RemoteMqttClient.SubscribeAsync (new MqttTopicFilter [] { topicFilterBusGateWayToClient, topicFilterPush2 });
                    if (result.Items [0].ResultCode == MQTTnet.Client.Subscribing.MqttClientSubscribeResultCode.GrantedQoS0) {
                        isSubscribeSuccess = true;
                        Utlis.WriteLine ("订阅成功!");
                        MqttRemoteSend (new byte [] { 0 }, 3);
                        //读取搜索网关,判断网关是否在线
                        CheckGatewaysIfOnline ();
                        ////连接成功后检测是否需要通过远程获取Key
                        //CheckIfNeedGetLocalPasswordFromRemote ();
                    }
                } catch (Exception ex) {
                    Console.WriteLine ("订阅catch:" + ex.Message.ToString ());
                }
            }
        }
        static DateTime mFlagDateTime;
        //static readonly object SendLocker = new object ();
        /// <summary>
        /// 启动远程Mqtt
        /// </summary>
        public static async System.Threading.Tasks.Task StartCloudMqtt ()
        public static async Task StartCloudMqtt ()
        {
            if (UserConfig.Instance.internetStatus == 0) {
                return;
            }
            if (!MainPage.LoginUser.IsLogin) {
                return;
            }
            //追加:没有远程连接的权限
            if (remoteMqttIsConnecting || remoteIsConnected) {
                return;
            }
            //lock (SendLocker) {
            //    remoteMqttIsConnecting = true;
            //}
            remoteMqttIsConnecting = true;
            await System.Threading.Tasks.Task.Factory.StartNew (async () => {
#if DEBUG
            Shared.Utlis.WriteLine ($"StartCloudMqtt: 开始");
#endif
            await Task.Factory.StartNew (async () => {
                try {
                    //lock (RemoteMqttClient) {
                    //表示后面将进行连接
                    //    //表示后面将进行连接
                    //    remoteMqttIsConnecting = true;
                    #region 初始化远程Mqtt
                    //2020-06-22 增加
                    RemoteMqttClient = new MqttFactory ().CreateMqttClient ();
                    //(3)当[连接云端的Mqtt成功后]或者[以及后面App通过云端Mqtt转发数据给网关成功后],处理接收到云端数据包响应时在mqttServerClient_ApplicationMessageReceived这个方法处理
                    if (RemoteMqttClient.ApplicationMessageReceivedHandler == null) {
                        RemoteMqttClient.UseApplicationMessageReceivedHandler (async (e) => {
                            try {
                                if (!RemoteMqttClient.IsConnected || !CommonPage.IsRemote) {
                                    return;
                                }
                                var aesDecryptTopic = e.ApplicationMessage.Topic;
                                var aesDecryptPayload = e.ApplicationMessage.Payload;
                                //Utlis.WriteLine ("Topic={0}", aesDecryptTopic);
                                //if (aesDecryptTopic == $"NotifyBusGateWayInfoChagne/{CurRemoteMACInfo.md5_mac_string}") {//网关上线,需要更新aeskey
                                //2020-01-11 修改订阅主题地址
                                if (aesDecryptTopic == $"/BusGateWayToClient/{CurRemoteMACInfo.macMark}/NotifyBusGateWayInfoChange") {//网关上线,需要更新aeskey                                                                                                                     //----第二步:读取账号下面的网关列表
                                    await ReceiveNotifyBusGateWayInfoChange ();
                                } else if (aesDecryptTopic == $"/BusGateWayToClient/{CurRemoteMACInfo.macMark}/NotifyGateWayOffline") {//网关掉线                                                                                                                    //----第二步:读取账号下面的网关列表
                    //(1)当[连接云端的Mqtt成功后]或者[以及后面App通过云端Mqtt转发数据给网关成功后],处理接收到云端数据包响应时在mqttServerClient_ApplicationMessageReceived这个方法处理
                    if (RemoteMqttClient.ApplicationMessageReceivedHandler == null) {
                        RemoteMqttClient.UseApplicationMessageReceivedHandler ((e) => {
                            try {
                                var topic = e.ApplicationMessage.Topic;
                                if (topic == $"/BusGateWayToClient/{MainPage.LoginUser.ID}" + PushNotifySqueeze) {
                                    var mMes = CommonPage.MyEncodingUTF8.GetString (e.ApplicationMessage.Payload);
                                    //新挤下线主题方案 收到挤下线主题
                                    ReceiveNotifySqueezeAsync (mMes);
                                } else if (topic == $"/BusGateWayToClient/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/NotifyBusGateWayInfoChange") {//网关上线,需要更新aeskey
                                    //收到网关上线消息主题
                                    ReceiveNotifyBusGateWayInfoChange ();
                                } else if (topic == $"/BusGateWayToClient/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/NotifyGateWayOffline") {//网关掉线                                                                                                                    //----第二步:读取账号下面的网关列表
                                    ReceiveNotifyGateWayOffline ();
                                } else if (aesDecryptTopic == $"/BusGateWayToClient/{mMqttInfo.connEmqClientId}/Push/NotifySqueeze") {//订阅挤下线问题
                                    await ReceiveNotifySqueezeAsync (aesDecryptPayload);
                                } else if (aesDecryptTopic == $"/BusGateWayToClient/{CurRemoteMACInfo.macMark}/Common/CheckGateway") {
                                    ReceiveCheckGatewayTopic ();
                                } else if (topic == $"/BusGateWayToClient/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/Common/CheckGateway") {
                                    var ss = CommonPage.MyEncodingUTF8.GetString (e.ApplicationMessage.Payload);
                                    ReceiveCheckGateway (ss);
                                } else {
                                    SetGatewayOnlineResetCheck ();
                                    if (!string.IsNullOrEmpty (mqttEncryptKey)) {
                                        aesDecryptPayload = Shared.Securitys.EncryptionService.AesDecryptPayload (e.ApplicationMessage.Payload, mqttEncryptKey);
                                    }
                                    var packet = new Packet ();
                                    if (!string.IsNullOrEmpty (mqttEncryptKey)) {
                                        packet.Bytes = Shared.Securitys.EncryptionService.AesDecryptPayload (e.ApplicationMessage.Payload, mqttEncryptKey);
                                    } else {
                                        packet.Bytes = e.ApplicationMessage.Payload;
                                    }
                                    packet.IsLocal = false;
                                    packet.Bytes = aesDecryptPayload;
                                    packet.Manager ();
                                }
                            } catch { }
                        });
                    }
                    //(2)DisconnectedHandler
                    if (RemoteMqttClient.DisconnectedHandler == null) {
                        RemoteMqttClient.UseDisconnectedHandler (async (e) => {
                            Utlis.WriteLine ($"============>Mqtt远程连接断开");
                            isSubscribeTopicSuccess = false;
                            await DisConnectRemoteMqttClient ("StartRemoteMqtt.DisconnectedHandler");
                            Shared.Utlis.WriteLine ($"远程连接断开");
                            isSubscribeSuccess = false;
                            await DisConnectRemoteMqttClient ("UseDisconnectedHandler");
                        });
                    }
                    //(3)ConnectedHandler
                    if (RemoteMqttClient.ConnectedHandler == null) {
                        RemoteMqttClient.UseConnectedHandler (async (e) => {
                            //IfNeedReadAllDeviceStatus = true;
                            mCheckGatewayTime = DateTime.Now;
                            CheckGatewayCount = 0;
                            bNeedStartTip = true;
                            IfNeedReadAllDeviceStatus = true;
                            bNeedStartTip = true;//
                            bNeedConnectTip = true;
                            Shared.Utlis.WriteLine ($"============>Mqtt远程连接成功");
                            SendPushSignOut ();
                            Utlis.WriteLine ($"============>Mqtt远程连接成功");
                            if (CommonPage.IsRemote) {
                                Utlis.ShowAppLinkStatus (AppLinkStatus.CloudLink);
                            }
                            if (CurRemoteMACInfo != null) {
                                IsGatewayOnline = CurRemoteMACInfo.isValid != "InValid";
                                if (!IsGatewayOnline) {
                                    //网关不在线
                                    if (CommonPage.IsRemote) {
                                        Utlis.ShowAppLinkStatus (AppLinkStatus.CloudOffline);
                                    }
                                    MainPage.AddTip ("Remote failed,gateway offline");
                                } else {
                                    //Remote Connection Succeeded
                                    //网关在线
                                    //重新一次所有设备状态
                                    IfNeedReadAllDeviceStatus = false;
                                    Shared.SimpleControl.Phone.UserMiddle.ReadAllDeviceStatus ();
                                    //
                                    MqttRemoteSend (new byte [] { 0 }, 3);
                                    if (CommonPage.IsRemote) {
                                        MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LinkSuccess));
                                    }
                                }
                            }
                            //if (CommonPage.IsRemote) {
                            //    //Utlis.ShowAppLinkStatus (AppLinkStatus.CloudLink);
                            //    MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LinkSuccess));
                            //}
                        });
                    }
                    #endregion
                    //}
                    //提示正在获取连接参数..."
                    ShowStartTip ();
                    mqttRequestParToken = MainPage.LoginUser.LoginTokenString;
                    //--判断是当前是否分享的住宅
                    if (!UserConfig.Instance.CurrentRegion.IsOthreShare) {
                        //主账号获取MQTT 远程链接信息,并连接
                        await GetMqttInfoAndMQTTConnectAsync ();
                    //(4)===========开始连接过程==========
                    //之前已经获取参数成功过
                    if (CommonConfig.Current.IfGetMqttInfoSuccess) {
                        //判断是否需要重新获取
                        await CheckMQTTConnectAsync ();
                    } else {
                        //如果是分享过来的住宅 走下面流程
                        await GetShareMqttInfoAndMQTTConnectAsync ();
                        //开始获取远程连接参数
                        await StartMQTTGetInfo ();
                    }
                } catch (Exception ex) {
                    //Utlis.WriteLine ($"============>Mqtt 远程连接通讯连接出异常:{ex.Message}");
                    MainPage.LoadingTipShow ("Connect error, trying to reconnect.");
                    Shared.Utlis.WriteLine ($"error:" + ex.Message);
                    if (IfDEBUG) {
                        MainPage.ShowAlertOnMainThread ("error: " + ex.Message);
                    }
                } finally {
                    //最终要释放连接状态
                    remoteMqttIsConnecting = false;
                    MainPage.LoadingTipHide ();
                    //lock (SendLocker) {
                    //    remoteMqttIsConnecting = false;
                    //}
                    //MainPage.LoadingHide ();
                    //连接成功才关闭Loading
                    if (remoteIsConnected) {
                        MainPage.LoadingTipHide ();
                        ERRORCount = 0;
                    } else {
                        ERRORCount++;
                        //每5次重新提示一次
                        if (ERRORCount > 5) {
                            ERRORCount = 0;
                            MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.RemoteFailure));
                            MainPage.LoadingTipHide ();
                        }
                    }
#if DEBUG
                    Shared.Utlis.WriteLine ($"StartCloudMqtt: 结束");
#endif
                }
            });
        }
        //static bool
        /// <summary>
        /// 主账号获取MQTT 远程链接信息,并连接
        /// 检查网关是否在线线程
        /// </summary>
        /// <returns></returns>
        static async Task GetMqttInfoAndMQTTConnectAsync ()
        static System.Threading.Thread CheckGatewaysThead;
        /// <summary>
        /// 网关对象
        /// </summary>
        public static Common GatewayCommon;
        /// <summary>
        /// 检查网关是否在线
        /// </summary>
        static void CheckGatewaysIfOnline ()
        {
            var mqttInfoRequestPar = new GetConnMqttInfoObj () {
                LoginAccessToken = MainPage.LoginUser.LoginTokenString,
                PlatformStr = "L1",
                PublishPayloadJsonStr = PushSignStr,
                Mac = UserConfig.Instance.GatewayMAC,
            };
            //----第一步:获取mqtt链接参数
            var mqttInfoRequestResult = MainPage.RequestHttps (API.GetConnMqttInfo, Newtonsoft.Json.JsonConvert.SerializeObject (mqttInfoRequestPar));
            if (GatewayCommon == null) return;
            if (mqttInfoRequestResult != null && mqttInfoRequestResult.ResponseData != null) {
                try {
                    var mqttInfoRequestResult_Obj = Newtonsoft.Json.JsonConvert.DeserializeObject<MqttInfo> (mqttInfoRequestResult.ResponseData.ToString ());
            try {
                //提示搜索网关中
                MainPage.LoadingTipShow (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.CheckingGatewayIsOnline));
                    if (mqttInfoRequestResult_Obj != null) {
                        mMqttInfo = mqttInfoRequestResult_Obj;
                        string url = mqttInfoRequestResult_Obj.connEmqDomainPort;
                        string clientId = mqttInfoRequestResult_Obj.connEmqClientId;
                        string username = mqttInfoRequestResult_Obj.connEmqUserName;
                        string passwordRemote = mqttInfoRequestResult_Obj.connEmqPwd;
                        if (mqttInfoRequestResult_Obj.AccountAllGateways != null && mqttInfoRequestResult_Obj.AccountAllGateways.Count > 0) {
                            //----第二步找出是否存在匹配当前住宅的mac,存在再进行远程。
                            CurRemoteMACInfo = mqttInfoRequestResult_Obj.AccountAllGateways.Find ((obj) => obj.mac == UserConfig.Instance.GatewayMAC);
                            if (CurRemoteMACInfo != null) {
                                CurRemoteMACInfo.LoginAccessToken = MainPage.LoginUser.LoginTokenString;
                                CurRemoteMACInfo.clientId = clientId;
                                //----第三步 开始连接
                                await MQTTConnectAsync ();
                            } else {
                                //Utlis.WriteLine ("============>Mqtt CurRemoteMACInfo null");
                if (CheckGatewaysThead != null)
                    CheckGatewaysThead.Abort ();
                                MainPage.LoadingTipShow ("Please wait, failed to get gateway parameters.");
                            }
                CheckGatewaysThead = new System.Threading.Thread (() => {
                    var returnBytes = Control.ControlBytesSendHasReturn (Command.ReadGateway, GatewayCommon.SubnetID, GatewayCommon.DeviceID, new byte [] { (byte)new Random ().Next (255), (byte)new Random ().Next (255) });
                    //隐藏提示
                    MainPage.LoadingTipHide ();
                    if (CommonPage.IsRemote) {
                        if (returnBytes == null) {
                            Application.RunOnMainThread (() => {
                                IsGatewayOnline = false;
                                Utlis.ShowAppLinkStatus (AppLinkStatus.CloudOffline);
                                MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.RemoteFailedGatewayOffline));
                                //发送一次CheckGateway主题
                                MqttRemoteSend (new byte [] { 0 }, 3);
                            });
                        } else {
                            MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LinkSuccess));
                            IsGatewayOnline = true;
                            Utlis.ShowAppLinkStatus (AppLinkStatus.CloudLink);
                            Console.WriteLine ("ReadGateway success");
                            CheckIfNeedReadAllDeviceStatus ();
                        }
                    } else {
                        //Utlis.WriteLine ("============>Mqtt mqttInfoRequestResult_Obj null");
                        MainPage.LoadingTipShow ("Please wait, failed to get user parameters.");
                        //MainPage.LoadingTipShow ("Please wait, failed to get parameters.");
                    }
                } catch {
                }) { IsBackground = true };
                }
            } else {
                //Utlis.WriteLine ("============>Mqtt GetInfo 失败");
                MainPage.AddTip ("Please wait, failed to get parameters.");
                //MainPage.LoadingTipShow ("Please wait, failed to get parameters.");
                CheckGatewaysThead.Start ();
            } catch {
            }
        }
        /// <summary>
        /// 子账号获取MQTT 远程链接信息,并连接
        /// 检测是否需要发送刷新获取所有设备的命令
        /// </summary>
        /// <returns></returns>
        static async Task GetShareMqttInfoAndMQTTConnectAsync ()
        static void CheckIfNeedReadAllDeviceStatus ()
        {
            var mqttInfoRequestPar = new ShareMemberConnMqttInfoObj () {
                LoginAccessToken = mqttRequestParToken,
                PlatformStr = "L1",
                PublishPayloadJsonStr = PushSignStr,
                //MainUserDistributedMark = UserConfig.Instance.CurrentRegion.MainUserDistributedMark,
                HomeId = UserConfig.Instance.CurrentRegion.Id
            };
            var mqttInfoRequestResult = MainPage.RequestHttps (API.ShareMemberConnMqttInfo, Newtonsoft.Json.JsonConvert.SerializeObject (mqttInfoRequestPar));
            //--第一步:获取mqtt链接参数
            if (mqttInfoRequestResult != null && mqttInfoRequestResult.ResponseData != null) {
                var mqttInfoRequestResult_info = Newtonsoft.Json.JsonConvert.DeserializeObject<MqttInfo> (mqttInfoRequestResult.ResponseData.ToString ());
                if (mqttInfoRequestResult_info != null) {
                    mMqttInfo = mqttInfoRequestResult_info;
                    //--第二步:获取当前住分享宅网关信息并连接MQTT
                    await GetSingleHomeGatewayPaggerAndMQTTConnectAsync ();
                } else {
                    MainPage.LoadingTipShow ("Please wait, failed to get user parameters.");
                }
            if (IfNeedReadAllDeviceStatus) {
                Utlis.WriteLine ("ReadAllDeviceStatus");
                IfNeedReadAllDeviceStatus = false;
                Shared.SimpleControl.Phone.UserMiddle.ReadAllDeviceStatus ();
            }
        }
        //连接错误次数统计
        static int ERRORCount = 0;
        /// <summary>
        /// 连接MQTT
        /// 是否需要提示
        /// </summary>
        static async Task MQTTConnectAsync ()
        {
            if (CurRemoteMACInfo != null && mMqttInfo != null) {
                //获取参数成功,开始连接...
                //MainPage.AddTip ("Successfully obtained parameters, starting to connect...");
                MainPage.LoadingTipShow ("Please wait, connecting remotely...");
                //try {
                //    var url = mMqttInfo.connEmqDomainPort;
                //    var clientId = mMqttInfo.connEmqClientId;
                //    var username = mMqttInfo.connEmqUserName;
                //    var passwordRemote = mMqttInfo.connEmqPwd;
                //    CurRemoteMACInfo.clientId = clientId;
                //    CurRemoteMACInfo.LoginAccessToken = MainPage.LoginUser.LoginTokenString;
                //    mqttEncryptKey = CurRemoteMACInfo.isNewBusproGateway ? CurRemoteMACInfo.aesKey : "";
                //    //mqttEncryptKey = CurRemoteMACInfo.aesKey;
                //    var options1 = new MQTTnet.Client.Options.MqttClientOptionsBuilder ()
                //                        .WithClientId (clientId)
                //                        .WithTcpServer (url.Split (':') [1].Substring ("//".Length), int.Parse (url.Split (':') [2]))
                //                        .WithCredentials (username, passwordRemote)
                //                        .WithCleanSession ()
                //                        // .WithCommunicationTimeout (new TimeSpan (0, 0, 20))
                //                        .Build ();
                //    await DisConnectRemoteMqttClient ("StartRemoteMqtt");
                //    await RemoteMqttClient.ConnectAsync (options1);
                //    remoteIsConnected = true;
                //    IsDisConnectingWithSendCatch = false;
                //} catch (Exception ex) {
                //    Console.WriteLine ("Connect error: " + ex.Message);
                //}
                //string mes = "";
                try {
                    var url = mMqttInfo.connEmqDomainPort;
                    var clientId = mMqttInfo.connEmqClientId;
                    var username = mMqttInfo.connEmqUserName;
                    var passwordRemote = mMqttInfo.connEmqPwd;
                    //mes = "step1.Set Data";
                    CurRemoteMACInfo.LoginAccessToken = MainPage.LoginUser.LoginTokenString;
                    mqttEncryptKey = CurRemoteMACInfo.aesKey;
                    var options1 = new MQTTnet.Client.Options.MqttClientOptionsBuilder ()
                                        .WithClientId (clientId)
                                        .WithTcpServer (url.Split (':') [1].Substring ("//".Length), int.Parse (url.Split (':') [2]))
                                        .WithCredentials (username, passwordRemote)
                                        .WithCleanSession ()
                                        // .WithCommunicationTimeout (new TimeSpan (0, 0, 20))
                                        .Build ();
                    //mes = "step2.DisConnect";
                    await DisConnectRemoteMqttClient ("StartRemoteMqtt");
                    //MainPage.AddTip ("Start to connect...");
                    //mes = "step3.Start to connect";
                    await RemoteMqttClient.ConnectAsync (options1);
                    //mes = "step4.Connected Success";
                    remoteIsConnected = true;
                    IsDisConnectingWithSendCatch = false;
                    MainPage.LoadingTipShow ("Remote connection succeeded.");
                    //MainPage.AddTip ("Connection succeeded!");
                    //await MqttRemoteSend (new byte [] { 0 }, 1);
                    //await MqttRemoteSend (new byte [] { 0 }, 2);
                    //await MqttRemoteSend (new byte [] { 0 }, 4);
                } catch (Exception ex) {
                    //mes = ex.Message;
                    //options1 异常提示
                    //Console.WriteLine ("Connect error: " + ex.Message);
                    MainPage.LoadingTipShow ("Connect error.");
                    if (IfDEBUG) {
                        MainPage.ShowAlertOnMainThread ("Connect error: " + ex.Message);
                    }
                } finally {
                    //MainPage.ShowAlertOnMainThread ("finally: " + mes);
                    //MainPage.AddTip ("finally: " + mes);
                }
            }
        }
        static bool bNeedConnectTip = true;
        /// <summary>
        /// 从开始到连接成功,只提示1次
@@ -517,10 +510,247 @@
            if (bNeedStartTip) {
                bNeedStartTip = false;
                if (CommonPage.IsRemote) {
                    //MainPage.AddTip ("Getting remote connection parameters...");
                    MainPage.LoadingTipShow ("Please wait, getting connection parameters...");
                    MainPage.LoadingTipShow (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GettingRemoteConnectionInfo));
                }
            }
            //if (CommonPage.IsRemote) {
            //    //MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GettingRemoteConnectionInfo));
            //    MainPage.LoadingTipShow (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GettingRemoteConnectionInfo));
            //}
        }
        /// <summary>
        /// 检测之前获取的Mac与当前住宅MAC是否一致 不一致从新获取
        /// </summary>
        /// <returns></returns>
        static async Task CheckMQTTConnectAsync ()
        {
            try {
                if (CommonConfig.Current.HomeGatewayInfo != null && CommonConfig.Current.HomeGatewayInfo.mac == UserConfig.Instance.GatewayMAC) {
                    await MQTTConnectAsync ();
                } else {
                    //Mac 变化了重新获取参数
                    await StartMQTTGetInfo ();
                }
            } catch {
                CommonConfig.Current.IfGetMqttInfoSuccess = false;
            }
        }
        /// <summary>
        /// 开始获取Mqtt 远程参数
        /// </summary>
        /// <returns></returns>
        static async Task StartMQTTGetInfo ()
        {
            ShowStartTip ();
            if (!CommonPage.IsRemote) {
                return;
            }
            await GetMqttInfoAndMQTTConnectAsync ();
            ////--判断是当前是否分享的住宅
            //if (!UserConfig.Instance.CurrentRegion.IsOthreShare) {
            //    //主账号获取MQTT 远程链接信息,并连接
            //    await GetMqttInfoAndMQTTConnectAsync ();
            //} else {
            //    //如果是分享过来的住宅 走下面流程
            //    //--第一步:获取当前住分享宅网关信息并连接MQTT
            //    await GetSingleHomeGatewayPaggerAndMQTTConnectAsync ();
            //}
        }
        /// <summary>
        /// 连接MQTT
        /// </summary>
        static async Task MQTTConnectAsync ()
        {
            if (!CommonPage.IsRemote) {
                return;
            }
            if (CommonConfig.Current.HomeGatewayInfo != null && CommonConfig.Current.mMqttInfo != null) {
                if (bNeedConnectTip) {
                    bNeedConnectTip = false;
                    MainPage.LoadingTipShow (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GetSuccessfullyStartConnecting));
                }
                try {
                    var url = CommonConfig.Current.mMqttInfo.url;
                    //url = HttpUtil.GetProxyEMQUrl (url);
                    //#if DEBUG
                    //                   url = HttpUtil.GetProxyEMQUrl (url);
                    //#endif
                    var clientId = CommonConfig.Current.mMqttInfo.clientId;
                    var username = CommonConfig.Current.mMqttInfo.userName;
                    var passwordRemote = CommonConfig.Current.mMqttInfo.passWord;
                    //获取参数成功,保存到本地并标记为true
                    CommonConfig.Current.IfGetMqttInfoSuccess = true;
                    CommonConfig.Current.Save ();
                    mqttEncryptKey = CommonConfig.Current.HomeGatewayInfo.aesKey;
                    var options1 = new MQTTnet.Client.Options.MqttClientOptionsBuilder ()
                                        .WithClientId (clientId)
                                        .WithTcpServer (url.Split (':') [1].Substring ("//".Length), int.Parse (url.Split (':') [2]))
                                        .WithCredentials (username, passwordRemote)
                                        .WithCleanSession ()
                                        .WithProtocolVersion (MQTTnet.Formatter.MqttProtocolVersion.V311)
                                        .WithCommunicationTimeout (new TimeSpan (0, 0, 10))
                                        //.WithCommunicationTimeout (new TimeSpan (0, 0, 5))
                                        //.WithCommunicationTimeout (new TimeSpan (0, 1, 0))
                                        .Build ();
                    await DisConnectRemoteMqttClient ("StartRemoteMqtt");
                    var mResult = await RemoteMqttClient.ConnectAsync (options1);
                    if (mResult.ResultCode == MQTTnet.Client.Connecting.MqttClientConnectResultCode.Success) {
                        remoteIsConnected = true;
                        IsDisConnectingWithSendCatch = false;
                        UnsupportedProtocolVersionCount = 0;
                    } else {
                        //重新中心服务器获取参数标记
                        CommonConfig.Current.IfGetMqttInfoSuccess = false;
                    }
                } catch (Exception ex) {
                    if (ex.Message == MqttCommunicationTimedOutException) {
                        Console.WriteLine ("Connect error TimedOut: " + ex.Message);
                    } else {
                        //重新中心服务器获取参数标记
                        CommonConfig.Current.IfGetMqttInfoSuccess = false;
                        Console.WriteLine ("Connect error: " + ex.Message);
                    }
                    //Console.WriteLine ("Connect error: " + ex.Message);
                    if (IfDEBUG) {
                        MainPage.ShowAlertOnMainThread ("Connect error: " + ex.Message);
                    }
                } finally {
                }
            } else {
                CommonConfig.Current.IfGetMqttInfoSuccess = false;
            }
        }
        static int UnsupportedProtocolVersionCount = 0;
        static readonly string MqttCommunicationTimedOutException = "Exception of type 'MQTTnet.Exceptions.MqttCommunicationTimedOutException' was thrown.";
        //
        static readonly string UnsupportedProtocolVersion = "Connecting with MQTT server failed (UnsupportedProtocolVersion).";
        /// <summary>
        /// 收到网关上线消息
        /// </summary>
        static void ReceiveNotifyBusGateWayInfoChange ()
        {
            try {
                SetGatewayOnlineResetCheck ();
                if (CommonPage.IsRemote) {
                    //#if DEBUG
                    MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GatewayLoginOnline));
                    //#endif
                    CheckIfNeedReadAllDeviceStatus ();
                }
                GetSingleHomeGatewayPaggerAndMQTTConnectAsync (false);
            } catch { }
        }
        /// <summary>
        /// 收到网关掉线信息
        /// </summary>
        static void ReceiveNotifyGateWayOffline ()
        {
            Shared.Utlis.WriteLine ("============>Mqtt GateWayOffline");
            IsGatewayOnline = false;
            if (CommonPage.IsRemote) {
                Utlis.ShowAppLinkStatus (AppLinkStatus.CloudOffline);
                MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GatewayOffline));
            }
        }
        /// <summary>
        /// 收到挤下线推送
        /// </summary>
        static void ReceiveNotifySqueezeAsync (string mMes)
        {
            if (mMes == PushSignStr) return;//是自己的登录推送不处理
            //断开远程连接
            CommonPage.IsRemote = false;
            if (!MainPage.LoginUser.IsLogin) {
                return;
            }
            DisConnectRemoteMqttClient ("挤下线");
            MainPage.LoginUser.LastTime = DateTime.MinValue;
            MainPage.LoginUser.SaveUserInfo ();
            Room.Lists.Clear ();
            Application.RunOnMainThread (() => {
                Utlis.ShowAppLinkStatus (AppLinkStatus.WiFi);
                new Shared.SimpleControl.Phone.AccountLogin (MainPage.LoginUser.AccountString, "").Show ();
                SharedMethod.SharedMethod.CurPageLayout = null;
                //CommonPage.IsRemote = false;
                MainPage.LoadingTipHide ();
                MainPage.Loading.Hide ();
                new Alert (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.Tip), Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LoggedOnOtherDevices),
                    Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.Close)).Show ();
            });
            //2020-08-11 删除推送数据
            //HDLRequest.Current.PushserivceSignOut ();
            //#if HDL
            //            if (!String.IsNullOrEmpty (MainPage.LoginUser.AllVisionRegisterDevUserNameGuid)) {
            //                com.freeview.global.Video.Logout ();
            //            }///BusGateWayToClient/320c1fea-1866-4708-8277-e2321a4dd236/NotifyGateWayInfoChange
            //#endif
        }
        /// <summary>
        /// 收到CheckGateway主题
        /// </summary>
        static void ReceiveCheckGateway (string mMes)
        {
            if (!CommonPage.IsRemote) return;
            Utlis.WriteLine ("ReceiveCheckGateway!");
            SetGatewayOnlineResetCheck ();
        }
        /// <summary>
        /// 推送挤下线主题
        /// </summary>
        static void SendPushSignOut ()
        {
            byte [] message = CommonPage.MyEncodingUTF8.GetBytes (PushSignStr);
            MqttRemoteSend (message, 4);
        }
        /// <summary>
@@ -531,338 +761,127 @@
        /// <returns></returns>
        public static async Task MqttRemoteSend (byte [] message, int optionType = 0)
        {
            try {
                //if (!remoteIsConnected) {
                //    Utlis.WriteLine ($"============>Mqtt 未连接 取消发送");
                //    return;
                //}
            //return;
            try {
                string topicName;
                switch (optionType) {
                case 0:
                    topicName = $"/ClientToBusGateWay/{CurRemoteMACInfo.macMark}/Common/ON";
                    topicName = $"/ClientToBusGateWay/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/Common/ON";
                    if (!string.IsNullOrEmpty (mqttEncryptKey)) {
                        message = Shared.Securitys.EncryptionService.AesEncryptPayload (message, mqttEncryptKey);
                    }
                    await RemoteMqttClient.PublishAsync (new MqttApplicationMessage { Topic = topicName, Payload = message, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce });
                    break;
                case 3:
                    topicName = $"/ClientToBusGateWay/{CurRemoteMACInfo.macMark}/Common/CheckGateway";
                    //Utlis.WriteLine ("CheckGateway");
                    topicName = $"/ClientToBusGateWay/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/Common/CheckGateway";
                    Shared.Utlis.WriteLine ("CheckGateway");
                    await RemoteMqttClient.PublishAsync (new MqttApplicationMessage { Topic = topicName, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce });
                    break;
                case 4://发布新方案的挤下线主题
                    topicName = $"/BusGateWayToClient/{MainPage.LoginUser.ID}" + PushNotifySqueeze;
                    //message = CommonPage.MyEncodingUTF8.GetBytes (PushSignStr);
                    await RemoteMqttClient.PublishAsync (new MqttApplicationMessage { Topic = topicName, Payload = message, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce });
                    break;
                }
            } catch (Exception e) {
                // Utlis.WriteLine ($"============>Mqtt MqttRemoteSend catch");
                 if (!IsDisConnectingWithSendCatch) {
                //Utlis.WriteLine ($"============>Mqtt MqttRemoteSend catch");
                if (!IsDisConnectingWithSendCatch) {
                    IsDisConnectingWithSendCatch = true;
                    await DisConnectRemoteMqttClient ("MqttRemoteSendCatch");
                    await DisConnectRemoteMqttClient ("SendCatch");
                }
            }
        }
        /// <summary>
        /// SendCatch 后执行一次断开操作
        /// </summary>
        static bool IsDisConnectingWithSendCatch = false;
        /// <summary>
        /// 分享住宅 获取当前住宅网关信息并且连接MQTT 或者刷新
        /// 2020-01-11
        /// </summary>
        static async Task GetSingleHomeGatewayPaggerAndMQTTConnectAsync (bool bNeedConnect = true)
        {
            var requestObj3 = new GetSingleHomeGatewayPaggerObj ();
            requestObj3.ReqDto.LoginAccessToken = MainPage.LoginUser.LoginTokenString;
            requestObj3.ReqDto.HomeId = UserConfig.Instance.CurrentRegion.Id;
            requestObj3.ReqDto.PageSetting.Page = 1;
            requestObj3.ReqDto.PageSetting.PageSize = 10;
            string urlHead = MainPage.RequestHttpsHost;
            if (requestObj3.IsOtherAccountCtrl) {
                urlHead = UserConfig.Instance.MasterAccountRequestBaseUrl;
                requestObj3.ReqDto.LoginAccessToken = UserConfig.Instance.MasterAccountToken;
            }
            var requestJson3 = Newtonsoft.Json.JsonConvert.SerializeObject (requestObj3);
            var revertObj3 = MainPage.RequestHttps (API.GetSingleHomeGatewayPagger, requestJson3, urlHead);
            if (revertObj3.StateCode.ToUpper () == StateCode.SUCCESS) {
                var infoResult = Newtonsoft.Json.JsonConvert.DeserializeObject<GetGatewayResult> (revertObj3.ResponseData.ToString ());
                if (bNeedConnect) {
                    //2020-01-11
                    UserConfig.Instance.SetNowHomeGateways (infoResult.PageData);
                    //var gatewayListRequestResult_Obj = Newtonsoft.Json.JsonConvert.DeserializeObject<MqttRemoteInfo> (revertObj3.ResponseData.ToString ());
                    //--找出是否存在匹配当前住宅的mac,存在再进行远程。
                    if (UserConfig.Instance.CheckHomeGatewaysNotEmpty ()) {
                        var mGatewayRes = infoResult.PageData.Find ((obj) => obj.GatewayUniqueId == UserConfig.Instance.HomeGateway.mac);
                        if (mGatewayRes != null) {
                            CurRemoteMACInfo = new RemoteMACInfo ();
                            CurRemoteMACInfo.aesKey = mGatewayRes.AesKey;
                            CurRemoteMACInfo.mac = mGatewayRes.GatewayUniqueId;
                            CurRemoteMACInfo.macMark = mGatewayRes.MacMark;
                            CurRemoteMACInfo.isValid = mGatewayRes.MqttOnlineStatus ? "Valid" : "InValid";
                            await MQTTConnectAsync ();
                        }
                    } else {
                        Utlis.WriteLine ("============>Mqtt 取消连接,当前住宅没绑定网关");
                    }
                } else {
                    var mGatewayRes = infoResult.PageData.Find ((obj) => obj.GatewayUniqueId == UserConfig.Instance.HomeGateway.mac);
                    if (mGatewayRes != null) {
                        CurRemoteMACInfo.aesKey = mGatewayRes.AesKey;
                        mqttEncryptKey = CurRemoteMACInfo.aesKey;
                    } else {
                        MainPage.LoadingTipShow ("Please wait, failed to get gateway parameters.");
                    }
                }
            }
        }
        /// <summary>
        /// 是否需要读取一次所有设备状态
        /// </summary>
        static bool IfNeedReadAllDeviceStatus = true;
        /// <summary>
        /// 收到网关上线消息
        /// </summary>
        static async Task ReceiveNotifyBusGateWayInfoChange ()
        {
            Utlis.WriteLine ("============>Mqtt 网关上线");
            SetGatewayOnlineResetCheck ();
            if (CommonPage.IsRemote) {
        public static bool IsGatewayOnline = true;
        //static int CheckGatewayCount = 0;
        //static DateTime mCheckGatewayTime;
//#if DEBUG
                MainPage.AddTip ("Gateway login online");
//#endif
                if (IfNeedReadAllDeviceStatus) {
                    IfNeedReadAllDeviceStatus = false;
                    Shared.SimpleControl.Phone.UserMiddle.ReadAllDeviceStatus ();
                }
            }
            //请求刷新一次 网关加密Key
            await GetSingleHomeGatewayPaggerAndMQTTConnectAsync (false);
        }
        /// <summary>
        /// 收到网关掉线信息
        /// </summary>
        static void ReceiveNotifyGateWayOffline ()
        {
            Utlis.WriteLine ("============>Mqtt GateWayOffline");
            IsGatewayOnline = false;
            if (CommonPage.IsRemote) {
                Utlis.ShowAppLinkStatus (AppLinkStatus.CloudOffline);
                MainPage.AddTip ("Remote failed,gateway offline");
                //if (MainPage.WiFiStatus != "CrabtreeAdd/CloudUnlink.png") {
                //    Utlis.ShowAppLinkStatus (AppLinkStatus.CloudUnlink);
                //}
            }
        }
        static int CheckGatewayCount = 0;
        static DateTime mCheckGatewayTime;
        /// <summary>
        /// 设置网关在线标志,并重置CheckGateway参数
        /// </summary>
        static void SetGatewayOnlineResetCheck ()
        {
            IsGatewayOnline = true;
            mCheckGatewayTime = DateTime.Now;
            CheckGatewayCount = 0;
            //mCheckGatewayTime = DateTime.Now;
            //CheckGatewayCount = 0;
            if (CommonPage.IsRemote) {
                if (MainPage.WiFiStatus != "CrabtreeAdd/CloudLink.png") {
                if (!IsGatewayOnline) {
                    IsGatewayOnline = true;
                    Utlis.ShowAppLinkStatus (AppLinkStatus.CloudLink);
                }
            }
        }
        //static void TipGatewayOffline () {
        //}
//        /// <summary>
//        /// 定时检测网关是否在线
//        /// 1.线程休眠间隔5s
//        /// 2.发送CheckGateway间隔为9S,收到主题刷新该时间,重置发送次数
//        /// 3.发送次数到达3次以上,则判定网关为离线状态
//        /// </summary>
//        /// <returns></returns>
//        static void InitCheckGateway ()
//        {
//            new System.Threading.Thread (async () => {
//                while (true) {
//                    try {
//                        if (CommonPage.IsRemote && remoteIsConnected) {
//                            if (CheckGatewayCount >= 3) {
//                                //连续3次没回复,判定网关超时
//                                if (MainPage.WiFiStatus == "CrabtreeAdd/CloudLink.png") {
//                                    //IsGatewayOnline = false;
//                                    Utlis.ShowAppLinkStatus (AppLinkStatus.CloudOffline);
//                                    MainPage.AddTip ("Gateway offline!");
//                                }
//                            }
//                            if (mCheckGatewayTime.AddSeconds (10).Ticks <= System.DateTime.Now.Ticks) {
//                                mCheckGatewayTime = DateTime.Now;
//                                //CheckGateway
//                                MqttRemoteSend (new byte [] { }, 3);
//                                CheckGatewayCount++;
//#if DEBUG
//                                Utlis.WriteLine ("CheckGateway");
//#endif
//                            }
//                        }
//                        System.Threading.Thread.Sleep (5500);
//                    } catch { }
//                }
//            }) { IsBackground = true }.Start ();
//        }
        /// <summary>
        /// 收到CheckGateway主题
        /// 主账号获取MQTT 远程链接信息,并连接
        /// </summary>
        static void ReceiveCheckGatewayTopic () {
            //Utlis.WriteLine ("============>Mqtt CheckGateway网关回复");
            SetGatewayOnlineResetCheck ();
        }
        /// <summary>
        /// 收到挤下线推送
        /// </summary>
        static async Task ReceiveNotifySqueezeAsync (byte [] mes)
        /// <returns></returns>
        static async Task GetMqttInfoAndMQTTConnectAsync ()
        {
            Utlis.WriteLine ($"============>MqttNotifySqueeze: {ErrorCode.LoginInAnotherDevice}");
            var mMes = CommonPage.MyEncodingUTF8.GetString (mes);
            if (mMes == PushSignStr) return;//是自己的登录推送不处理
            var mqttInfoRequestResult_Obj = HttpServerRequest.Current.GetMqttRemoteInfo (GetRandomKey ());
            if (mqttInfoRequestResult_Obj != null) {
                CommonConfig.Current.mMqttInfo = mqttInfoRequestResult_Obj;
                if (UserConfig.Instance.CheckHomeGatewaysNotEmpty()) {
                    //----第二步找出是否存在匹配当前住宅的mac,存在再进行远程。
                    CommonConfig.Current.HomeGatewayInfo = UserConfig.Instance.HomeGateway;
                    if (CommonConfig.Current.HomeGatewayInfo != null) {
                        //----第三步 开始连接
                        await MQTTConnectAsync ();
                    }
                } else {
                    Utlis.WriteLine ("============>还没绑定网关");
                }
            CommonPage.IsRemote = false;
            //if (MainPage.IsOtherDevicesLogin) return;
            if (!MainPage.LoginUser.IsLogin) {
                return;
            } else {
                Utlis.WriteLine ("============>MqttInfo null");
            }
            MainPage.LoginUser.LastTime = DateTime.Now.AddDays (-30);
            MainPage.LoginUser.SaveUserInfo ();
            DisConnectRemoteMqttClient ("挤下线");
            MainPage.ShowAlertOnMainThread (ErrorCode.LoginInAnotherDevice);
            Application.RunOnMainThread (() => {
                MainPage.WiFiStatus = "CrabtreeAdd/WiFi.png";
                UserMiddle.btnLinkStatus.UnSelectedImagePath = MainPage.WiFiStatus;
                new AccountLogin ().Show ();
            });
        }
        /// <summary>
        /// 分享住宅 获取当前住宅网关信息并且连接MQTT 或者刷新
        /// 2020-03-17
        /// </summary>
        static async Task GetSingleHomeGatewayPaggerAndMQTTConnectAsync (bool bNeedConnect = true)
        {
        }
    }
}
public class ShareMemberConnMqttInfoObj : GetConnMqttInfoObj
{
    /// <summary>
    /// 主人用户Id
    /// </summary>
    public string MainUserDistributedMark;
    /// <summary>
    /// 分享者住宅Id
    /// </summary>
    public string HomeId;
}
public class GetConnMqttInfoObj : BaseRequestObj
{
    /// <summary>
    /// HdlGatewayGatewayType 网关类型(0:一端口、1:BusproLinux 网关、2:Zigbee 网关、3:Knx网关)
    /// </summary>
    public int HdlGatewayGatewayType = 0;
    /// <summary>
    /// 设备类型字段
    /// </summary>
    public string PlatformStr = "";
    /// <summary>
    ///
    /// </summary>
    public string PublishPayloadJsonStr = "";
    /// <summary>
    /// Mac
    /// </summary>
    public string Mac = "";
}
public class RemoteRequestParameters
{
    public string RequestVersion;
    public int RequestSource;
    public string LoginAccessToken;
    public int RequestProtocolType;
    public string Mac = "";
    public string GroupName = "";
}
public class MqttRemoteInfo
{
    public List<RemoteMACInfo> pageData;
    public int pageIndex = 0;
    public int pageSize = 10;
    public int totalCount = 3;
    public int totalPages = 1;
    public bool hasPreviousPage = false;
    public bool hasNextPage = false;
}
public class MqttInfo
{
    public string connEmqDomainPort;
    public string connEmqClientId;
    public string connEmqUserName;
    public string connEmqPwd;
    public List<RemoteMACInfo> AccountAllGateways;
}
public class RemoteMACInfo
{
    public string mac;
    public string macMark;
    public string isValid;
    public string aesKey;
    public bool isNewBusproGateway;
    public string groupName;
    public string projectName;
    public string userName;
    /// <summary>
    ///
    /// </summary>
    public string url;
    /// <summary>
    ///
    /// </summary>
    public string clientId;
    //app自定义数据
    public string md5_mac_string;
    public string LoginAccessToken;
    /// <summary>
    ///
    /// </summary>
    public string userName;
    /// <summary>
    ///
    /// </summary>
    public string passWord;
}
namespace Shared.Securitys
@@ -983,503 +1002,6 @@
        #endregion
    }
}
/*
using System.Collections.Generic;
using System;
using MQTTnet.Client;
using System.Threading.Tasks;
using Shared;
using Shared.SimpleControl;
using MQTTnet;
using System.Text;
using System.Security.Cryptography;
namespace SmartHome
{
    public static class MqttCommon
    {
        static string mqttEncryptKey = "";
        static string checkGatewayTopicBase64 = "";
        /// <summary>
        /// 手机标识
        /// </summary>
        static Guid currentGuid = Guid.NewGuid ();
        /// <summary>
        /// 外网的MQTT是否正在连接
        /// </summary>
        static object isConnecting = false.ToString ();
        /// <summary>
        /// 远程MqttClient
        /// </summary>
        public static IMqttClient RemoteMqttClient;
        static bool thisShowTip = true;
        public static async Task Close (bool RemoveRemoteMqttClient = false)
        {
            try {
                if (RemoteMqttClient != null) {
                    //thisShowTip = true;
                    await RemoteMqttClient.DisconnectAsync ();
                }
                if (RemoveRemoteMqttClient) {
                    RemoteMqttClient = null;
                }
                CommonPage.IsRemote = false;
                Utlis.WriteLine ("Close Mqtt!!!");
            } catch { }
        }
        static DateTime dateTime = DateTime.MinValue;
        static int startCount = 0;
        //public static async Task ReSatart ()
        //{
        //    await Close ();
        //    await RemoteMqttClient.ConnectAsync (options);
        //}
        /// <summary>
        /// 启动远程Mqtt
        /// </summary>
        public static async System.Threading.Tasks.Task StartCloudMqtt ()
        {
            Application.RunOnMainThread (() => {
                if (5 < (DateTime.Now - dateTime).TotalSeconds) {
                    return;
                }
                dateTime = DateTime.Now;
            });
            if (!MainPage.LoginUser.IsLogin) {
                isConnecting = false.ToString ();
                return;
            }
            while (isConnecting.ToString () == true.ToString ()) {
                if (5 < (DateTime.Now - dateTime).TotalSeconds) {
                    break;
                }
                await System.Threading.Tasks.Task.Delay (500);
            }
            lock (isConnecting) {
                if (isConnecting.ToString () == true.ToString ()) {
                    return;
                }
                isConnecting = true.ToString ();
                if (RemoteMqttClient != null && RemoteMqttClient.IsConnected) {
                    MqttCheckGateway ();
                    return;
                }
            }
            new System.Threading.Thread (async () => {
                try {
                    if (RemoteMqttClient == null) {
                        var requestObj3 = new GatewayByRegionListObj () { RegionID = UserConfig.Instance.CurrentRegion.RegionID };
                        var requestJson3 = Newtonsoft.Json.JsonConvert.SerializeObject (requestObj3);
                        var revertObj3 = MainPage.RequestHttps ("GatewayByRegionList", requestJson3, true, false);
                        if (revertObj3.StateCode.ToUpper() == StateCode.SUCCESS) {
                            var responseDataObj = Newtonsoft.Json.JsonConvert.DeserializeObject<List<GatewayRes>> (revertObj3.ResponseData.ToString ());
                            var gatewayList = responseDataObj;
                            if (gatewayList != null && gatewayList.Count > 0) {
                                UserConfig.Instance.CurrentRegion.MAC = gatewayList [0].MAC;
                                UserConfig.Instance.SaveUserConfig ();
                            }
                        } else {
                        }
                        //(2)创建Mqtt客户端
                        RemoteMqttClient = new MqttFactory ().CreateMqttClient ();
                        //(3)当[连接云端的Mqtt成功后]或者[以及后面App通过云端Mqtt转发数据给网关成功后],处理接收到云端数据包响应时在mqttServerClient_ApplicationMessageReceived这个方法处理
                        RemoteMqttClient.UseApplicationMessageReceivedHandler (async e => {
                            if (isConnecting.ToString () == true.ToString ())
                                isConnecting = false.ToString ();
                            var aesDecryptTopic = e.ApplicationMessage.Topic;
                            var aesDecryptPayload = e.ApplicationMessage.Payload;
                            if (aesDecryptTopic == "YouIpAndPortNoRecord" || aesDecryptTopic == "DecryptFail") {// -->   你当前的IP及端口在云端不存在,请重新登录连接下!
                                await Close (true);
                                await MqttCheckGateway ();
                            } else if (aesDecryptTopic == @"/BeingSqueezedOffline") {
                                try {
                                    Application.RunOnMainThread (() => {
                                        MainPage.Loading.Start ("");
                                        MainPage.LoginUser.LastTime = DateTime.MinValue;
                                        MainPage.LoginUser.SaveUserInfo ();
                                        Room.Lists.Clear ();
                                        new Shared.SimpleControl.Phone.AccountLogin (MainPage.LoginUser.AccountString.ToLower (), "").Show ();
                                        MainPage.LoginUser.LastTime = System.DateTime.MinValue;
                                        Shared.SimpleControl.Phone.UserMiddle.LinkStatusTip.BackgroundColor = SkinStyle.Current.LinkStatusTipColor;
                                        if (CommonPage.IsRemote) {
                                            SmartHome.MqttCommon.Close (true);
                                        }
                                        var webPush = new service.hdlcontrol.com_push.WebServicePush ();
                                        webPush.DeleteToken_Push (UserConfig.Instance.tokenID);
                                    });
                                } catch (Exception ex) {
                                    Utlis.WriteLine (ex.Message);
                                } finally {
                                    Application.RunOnMainThread (() => {
                                        Shared.SimpleControl.Phone.UserMiddle.LinkStatusTip.BackgroundColor = SkinStyle.Current.LinkStatusTipColor;
                                        MainPage.Loading.Hide ();
                                        new Alert (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.Tip), Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LoggedOnOtherDevices),
                                            Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.Close)).Show ();
                                    });
                                }
#if HDL
                                if (!String.IsNullOrEmpty (MainPage.LoginUser.AllVisionRegisterDevUserNameGuid)) {
                                    com.freeview.global.Video.Logout ();
                                }
#endif
                            } else {
                                aesDecryptTopic = Shared.Securitys.EncryptionService.AesDecryptTopic (e.ApplicationMessage.Topic, mqttEncryptKey);
                                aesDecryptPayload = Shared.Securitys.EncryptionService.AesDecryptPayload (e.ApplicationMessage.Payload, mqttEncryptKey);
                            }
                            if (aesDecryptTopic == @"/" + MainPage.LoginUser.AccountString.ToLower () + @"/CheckGateway/" + UserConfig.Instance.GatewayMAC.Replace (".", "")) {
                                var ss = CommonPage.MyEncodingUTF8.GetString (aesDecryptPayload);
                                var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePack> (ss);
                                if (obj == null) {
                                    return;
                                }
                                switch (obj.StateCode) {
                                case "HDLUdpDataForwardServerMqttClientNoOnLine":
                                case "NoOnline":
                                case "NetworkAnomaly"://不在线
                                    MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.RemoteFailedGatewayOffline));
                                    Application.RunOnMainThread (() => {
                                        MainPage.Loading.Hide ();
                                        Shared.SimpleControl.Phone.UserMiddle.LinkStatusTip.BackgroundColor = SkinStyle.Current.DelColor;
                                    });
                                    break;
                                case "NoRecord"://MAC不正确
                                    MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.MACError));
                                    Application.RunOnMainThread (() => {
                                        MainPage.Loading.Hide ();
                                        Shared.SimpleControl.Phone.UserMiddle.LinkStatusTip.BackgroundColor = SkinStyle.Current.DelColor;
                                    });
                                    break;
                                case StateCode.SUCCESS:
                                    CommonPage.IsRemote = true;
                                    Application.RunOnMainThread (() => {
                                        MainPage.Loading.Hide ();
                                        Shared.SimpleControl.Phone.UserMiddle.LinkStatusTip.BackgroundColor = 0xAA69E64A;
                                        Shared.SimpleControl.Phone.UserMiddle.ReadAllDeviceStatus ();
                                    });
                                    MainPage.AddTip (UserConfig.Instance.CurrentRegion.RegionName + ":" + Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LinkSuccess));
                                    break;
                                default:
                                    MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LinkLoser));
                                    Application.RunOnMainThread (() => {
                                        MainPage.Loading.Hide ();
                                        Shared.SimpleControl.Phone.UserMiddle.LinkStatusTip.BackgroundColor = SkinStyle.Current.DelColor;
                                    });
                                    break;
                                }
                            } else {
                                var packet = new Packet ();
                                packet.Bytes = aesDecryptPayload;
                                packet.Manager ();
                            }
                        });
                        RemoteMqttClient.UseDisconnectedHandler (e => {
                            //Utlis.WriteLine ("RemoteMqttClient UseDisconnectedHandler");
                            if (thisShowTip) {
                                if (CommonPage.IsRemote) {
                                    //MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.RemoteConnectionDisconnected));
                                    Application.RunOnMainThread (() => {
                                        MainPage.Loading.Hide ();
                                        Shared.SimpleControl.Phone.UserMiddle.LinkStatusTip.BackgroundColor = SkinStyle.Current.DelColor;
                                    });
                                }
                            } else {
                                thisShowTip = true;
                            }
                        });
                        RemoteMqttClient.UseConnectedHandler (async e => {
                            //Utlis.WriteLine ("RemoteMqttClient IsRemote");
                            await MqttCheckGateway ();
                        });
                    }
                    var requestObj = new LoginObj () { Account = MainPage.LoginUser.AccountString.ToLower (), Password = MainPage.LoginUser.Password, Company = MainPage.SoftSmsType };
                    var requestJson = Newtonsoft.Json.JsonConvert.SerializeObject (requestObj);
                    var tempResult = MainPage.RequestHttps ("Login", requestJson, false);
                    if (tempResult == null) {
                        Application.RunOnMainThread (() => {
                            MainPage.Loading.Hide ();
                            Shared.SimpleControl.Phone.UserMiddle.LinkStatusTip.BackgroundColor = SkinStyle.Current.DelColor;
                        });
                        Utlis.WriteLine ($"重新连接远程通讯失败,因为获取新的KEY失败");
                        return;
                    }
                    //var messgae = System.Text.Encoding.UTF8.GetString (tempResult);
                    var responsePack = tempResult.ResponseData;// Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>> (messgae);
                    //if (responsePack == null || responsePack ["ResponseData"] == null) {
                    //    Utlis.WriteLine ("断开后重新链接需要重新登录获取连接的密码失败");
                    //    return;
                    //}
                    var dictrionaryResult = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>> (tempResult.ResponseData.ToString ());
                    //var dictrionaryResult = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>> (responsePack ["ResponseData"].ToString ());
                    //////还有种情况是同一个ID 有多个设备用这个id连接(会导致中断)
                    mqttEncryptKey = dictrionaryResult ["HdlOnMqttKey"]?.ToString ();
                    var url = dictrionaryResult ["ConnectMqttBrokerLoadSubDomain"]?.ToString ();
                    var clientId = dictrionaryResult ["ConnectMqttClientId"]?.ToString ();
                    var username = dictrionaryResult ["ConnectMqttBrokerUserName"]?.ToString ();
                    var passwordRemote = dictrionaryResult ["ConnectMqttBrokerPwd"]?.ToString ();
                    if (clientId == null || username == null || passwordRemote == null) {
                        return;
                    }
                    ////(1)连接到云端的Mqtt客户端连接参数
                    var options = new MQTTnet.Client.Options.MqttClientOptionsBuilder ()
                                 .WithClientId (clientId)
                                 .WithTcpServer (url.Split (':') [1].Substring ("//".Length), int.Parse (url.Split (':') [2]))//
                                 .WithCredentials (username, passwordRemote)
                                 .WithCleanSession ()
                                 .WithCommunicationTimeout (new TimeSpan (0, 0, 10))
                                 .Build ();
                    await Close ();
                    await RemoteMqttClient.ConnectAsync (options);
                } catch (Exception ex) {
                    Utlis.WriteLine ("============>" + ex.Message);
                    Application.RunOnMainThread (() => {
                        MainPage.Loading.Hide ();
                        isConnecting = false.ToString ();
                        Shared.SimpleControl.Phone.UserMiddle.LinkStatusTip.BackgroundColor = SkinStyle.Current.DelColor;
#if DEBUG
                        Alert a = new Alert (isConnecting.ToString (), ex.Message, "Close");
                        a.Show ();
#endif
                        if (MqttCommon.RemoteMqttClient != null) {
                            MqttCommon.RemoteMqttClient.Dispose ();
                        }
                        if (MqttCommon.RemoteMqttClient != null) {
                            MqttCommon.RemoteMqttClient = null;
                        }
                    });
                } finally {
                    isConnecting = false.ToString ();
                    Application.RunOnMainThread (() => {
                        MainPage.Loading.Hide ();
                    });
                }
            }) { IsBackground = true }.Start ();
        }
        /// <summary>
        /// Logins the by PWDA sync.
        /// </summary>
        public static async System.Threading.Tasks.Task<byte []> LoginByPWDAsync (string account, string password, string source = "", int company = 0)
        {
            try {
                var result = await MainPage.RequestHttpsResultAsync ("Login",
                System.Text.Encoding.UTF8.GetBytes (Newtonsoft.Json.JsonConvert.SerializeObject (new Dictionary<string, object> {
                    ["Account"] = account,
                    ["Password"] = password,
                    ["Source"] = source,
                    ["Company"] = company
                })));
                return result;
            } catch {
                return null;
            }
        }
        /// <summary>
        /// 将Base64字符串,转换成合法的Mqtt主题
        /// </summary>
        /// <param name="baseSexFourEncStr"></param>
        /// <returns></returns>
        public static string BaseSexFourStrToMqttTopic (string baseSexFourEncStr)
        {
            baseSexFourEncStr = baseSexFourEncStr.Replace ("+", "[[$-MQTT_PLUS_SYMBOL_REPLACE-$]]");
            baseSexFourEncStr = baseSexFourEncStr.Replace ("/", "[[$-MQTT_TILT_SYMBOL_REPLACE-$]]");
            return baseSexFourEncStr;
        }
        public static async System.Threading.Tasks.Task MqttRemoteSend (byte [] message)
        {
            try {
                if (RemoteMqttClient == null || !RemoteMqttClient.IsConnected) {
                    await StartCloudMqtt ();
                }
                if (!RemoteMqttClient.IsConnected) {
                    return;
                }
                var topicName = @"/" + MainPage.LoginUser.AccountString.ToLower () + @"/" + UserConfig.Instance.GatewayMAC.Replace (".", "") + @"/" + currentGuid;
                //base64加密主题
                checkGatewayTopicBase64 = Shared.Securitys.EncryptionService.AesEncryptTopic (topicName, mqttEncryptKey);
                //BaseSexFourStrToMqttTopic
                var topicNameSend = BaseSexFourStrToMqttTopic (checkGatewayTopicBase64);
                //base64加密主体
                var messageSend = Shared.Securitys.EncryptionService.AesEncryptPayload (message, mqttEncryptKey);
                var m = new MqttApplicationMessage { Topic = topicNameSend, Payload = messageSend, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce };
                await RemoteMqttClient?.PublishAsync (m);
            } catch (Exception e) {
                isConnecting = false.ToString ();
            }
        }
        public static async Task MqttCheckGateway ()
        {
            try {
                if (RemoteMqttClient == null || !RemoteMqttClient.IsConnected) {
                    await StartCloudMqtt ();
                }
                if (!RemoteMqttClient.IsConnected) {
                    return;
                }
                var topicName = @"/" + MainPage.LoginUser.AccountString.ToLower () + @"/CheckGateway/" + UserConfig.Instance.GatewayMAC.Replace (".", "");
                Utlis.WriteLine ("MqttCheckGateway : " + topicName);
                //base64加密主题
                var topicNameBase64 = Shared.Securitys.EncryptionService.AesEncryptTopic (topicName, mqttEncryptKey);
                //BaseSexFourStrToMqttTopic
                var topicNameSend = BaseSexFourStrToMqttTopic (topicNameBase64);
                //base64加密主题
                var messageSend = Shared.Securitys.EncryptionService.AesEncryptPayload (new byte [] { 2, 1 }, mqttEncryptKey);
                var m = new MqttApplicationMessage { Topic = topicNameSend, Payload = messageSend, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce };
                await RemoteMqttClient?.PublishAsync (m);
            } catch (Exception e) {
                isConnecting = false.ToString ();
            }
        }
    }
}
namespace Shared.Securitys
{
    public partial class EncryptionService
    {
        #region 加密
        /// <summary>
        /// 加密主题为Base64
        /// </summary>
        /// <param name="pToEncrypt"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string AesEncryptTopic (string pToEncrypt, string key)
        {
            if (string.IsNullOrEmpty (pToEncrypt)) return null;
            //需要加密内容的明文流
            Byte [] toEncryptArray = Encoding.UTF8.GetBytes (pToEncrypt);
            //配置AES加密Key(密钥、向量、模式、填充)
            RijndaelManaged rm = new RijndaelManaged {
                Key = Encoding.UTF8.GetBytes (key),
                IV = Encoding.UTF8.GetBytes (key),
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7
            };
            //创建AES加密器对象
            ICryptoTransform cTransform = rm.CreateEncryptor ();
            //使用AES将明文流转成密文字节数组
            Byte [] resultArray = cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length);
            //将AES生成的密文字节数组转成Base64字符串
            return Convert.ToBase64String (resultArray, 0, resultArray.Length);
        }
        /// <summary>
        /// 加密负载为二进制流
        /// </summary>
        /// <param name="toEncryptArray"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte [] AesEncryptPayload (byte [] toEncryptArray, string key)
        {
            //配置AES加密Key(密钥、向量、模式、填充)
            var rm = new RijndaelManaged {
                Key = Encoding.UTF8.GetBytes (key),
                IV = Encoding.UTF8.GetBytes (key),
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7
            };
            //创建AES加密器对象
            var cTransform = rm.CreateEncryptor ();
            //使用AES将明文流转成密文字节数组
            return cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length);
        }
        #endregion
        #region 解密
        /// <summary>
        /// 解密主题数据
        /// </summary>
        /// <param name="pToDecrypt"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string AesDecryptTopic (string pToDecrypt, string key)
        {
            //AES密文Base64转成字符串
            Byte [] toEncryptArray = Convert.FromBase64String (pToDecrypt);
            //配置AES加密Key(密钥、向量、模式、填充)
            RijndaelManaged rm = new RijndaelManaged {
                Key = Encoding.UTF8.GetBytes (key),
                IV = Encoding.UTF8.GetBytes (key),
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7
            };
            //创建AES解密器对象
            ICryptoTransform cTransform = rm.CreateDecryptor ();
            //使用AES将密文流转成明文的字节数组
            Byte [] resultArray = cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length);
            //转成字符串
            return Encoding.UTF8.GetString (resultArray);
        }
        /// <summary>
        /// 采用Aes解密负载数据
        /// </summary>
        /// <param name="toEncryptArray"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte [] AesDecryptPayload (byte [] toEncryptArray, string key)
        {
            //配置AES加密Key(密钥、向量、模式、填充)
            var rm = new RijndaelManaged {
                Key = Encoding.UTF8.GetBytes (key),
                IV = Encoding.UTF8.GetBytes (key),
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7
            };
            //创建AES解密器对象
            var cTransform = rm.CreateDecryptor ();
            //使用AES将密文流转成明文的字节数组
            return cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length);
        }
        #endregion
    }
}
*/