wei
2021-03-03 d4811b7d34b45ff6b21b97f11da128b5572ec526
HDL_ON/DAL/Mqtt/MqttClient.cs
@@ -10,6 +10,7 @@
using System.Security.Cryptography;
using HDL_ON.DriverLayer;
using HDL_ON.Entity;
using HDL_ON.UI;
namespace HDL_ON.DAL.Mqtt
{
@@ -19,8 +20,9 @@
        /// 加密通讯KEY
        /// </summary>
        static string mqttEncryptKey = "";
        static string tuyaEncryptKey = "";
        //static string checkGatewayTopicBase64 = "";
        static bool hadGateway = true;
        /// <summary>
        /// 挤下线主题
        /// </summary>
@@ -31,18 +33,18 @@
        /// </summary>
        static string RandomKey = "";
        /// <summary>
        /// 随机生成字符
        /// </summary>
        /// <returns></returns>
        static string GetRandomKey()
        {
            if (string.IsNullOrEmpty(RandomKey))
            {
                //随机2位字符串
                Random random = new Random(Guid.NewGuid().GetHashCode());
                int num = random.Next(65, 91);
                RandomKey = Convert.ToChar(num).ToString();
                RandomKey = Utlis.CreateRandomString(2);
            }
            return RandomKey;
        }
        /// <summary>
@@ -55,37 +57,32 @@
        /// </summary>
        static string PushSignStr = DateTime.Now.Ticks.ToString();
        /// <summary>
        /// 断开远程Mqtt的链接
        /// <summary>
        /// 断开远程Mqtt的链接
        /// </summary>
        static async Task DisConnectRemoteMqttClient(string s = "")
        {
        static async Task DisConnectRemoteMqttClient(string s = "")
        {
            try
            {
            {
                if (remoteIsConnected)
                {
                    remoteIsConnected = false;
                    isSubscribeSuccess = false;
                    Utlis.WriteLine($"Remote主动断开_{s}");
                    //await RemoteMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions { }, CancellationToken.None);
                    Utlis.WriteLine($"Remote主动断开_{s}");
                    //await RemoteMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions { }, CancellationToken.None);
                    await RemoteMqttClient.DisconnectAsync();
                    if (Control.Ins.IsRemote)
                    {
                        Control.Ins.GatewayOnline = false;
                    }
                }
                }
            }
            catch (Exception e)
            {
                Utlis.WriteLine($"Remote断开通讯连接出异常:{e.Message}");
            }
                Utlis.WriteLine($"Remote断开通讯连接出异常:{e.Message}");
            }
        }
        /// <summary>
        /// 断开远程Mqtt的链接
        /// <summary>
        /// 断开远程Mqtt的链接
        /// </summary>
        static async Task DisConnectRemoteMqttClientWhenStart(string s = "")
        static async Task DisConnectRemoteMqttClientWhenStart(string s = "")
        {
            try
            {
@@ -96,7 +93,7 @@
            }
            catch (Exception e)
            {
                Utlis.WriteLine($"RemoteStart断开通讯连接出异常:{e.Message}");
                Utlis.WriteLine($"RemoteStart断开通讯连接出异常:{e.Message}");
            }
        }
@@ -118,7 +115,7 @@
        /// <summary>
        /// 外网的MQTT是否正在连接
        /// </summary>
        public static bool remoteMqttIsConnecting;
        public static bool RemoteMqttIsConnecting;
        static bool remoteIsConnected;
        static MqttClient()
@@ -136,7 +133,12 @@
                    try
                    {
                        System.Threading.Thread.Sleep(500);
                        if (!Control.Ins.IsRemote) continue;
                        //进入后台不处理
                        if (MainPage.IsEnterBackground) continue;
                        if (MqttInfoConfig.Current.HomeGatewayInfo == null)
                        {
                            continue;
                        }
                        await StartCloudMqtt();
                        await SubscribeTopics();
@@ -157,44 +159,45 @@
        }
        static bool isSubscribeSuccess;
        /// <summary>
        /// 订阅主题
        /// </summary>
        /// <returns></returns>
        static async Task SubscribeTopics()
        {
            if (remoteIsConnected && !isSubscribeSuccess)
            {
                try
                {
                    //2020-05-14 订阅主题质量改为0
                    var topicFilterBusGateWayToClient = new MqttTopicFilter()
                    if (DB_ResidenceData.Instance.GatewayType == 0 && !DB_ResidenceData.Instance.CheckWhetherGatewayIdIsNull())
                    {
                        Topic = $"/BusGateWayToClient/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/#",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                        //QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    };
                        Utlis.WriteLine("开始订阅一端口通用主题!");
                        //2020-05-14 订阅主题质量改为0
                        var topicFilterBusGateWayToClient = new MqttTopicFilter()
                        {
                            Topic = $"/BusGateWayToClient/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/#",
                            QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                        };
                        await RemoteMqttClient.SubscribeAsync(topicFilterBusGateWayToClient);
                    }
                    //挤下线主题
                    var topicFilterPush2 = new MqttTopicFilter
                    {
                        Topic = $"/BusGateWayToClient/{UserInfo.Current.ID}/#",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce,
                        //QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
                    };
                    var topicAlinkStatus = new MqttTopicFilter()
                    {
                        Topic = $"/user/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/app/thing/property/#",
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.RegionID}/app/thing/property/send",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                    };
                    Utlis.WriteLine("开始订阅!");
                    var result = await RemoteMqttClient.SubscribeAsync(new MqttTopicFilter[] { topicFilterBusGateWayToClient, topicFilterPush2 , topicAlinkStatus });
                    var result = await RemoteMqttClient.SubscribeAsync(new MqttTopicFilter[] {  topicFilterPush2, topicAlinkStatus });
                    if (result.Items[0].ResultCode == MQTTnet.Client.Subscribing.MqttClientSubscribeResultCode.GrantedQoS0)
                    {
                        isSubscribeSuccess = true;
                        Utlis.WriteLine("订阅成功!");
                        MqttRemoteSend(new byte[] { 0 }, 3);
                        //连接成功后检测是否需要通过远程获取Key
                        //CheckIfNeedGetLocalPasswordFromRemote();
                    }
                }
                catch (Exception ex)
@@ -209,8 +212,7 @@
        /// </summary>
        public static async Task StartCloudMqtt()
        {
            if (OnAppConfig.Instance.internetStatus == 0)
            if (MainPage.InternetStatus == 0)
            {
                return;
            }
@@ -221,7 +223,7 @@
            }
            //追加:没有远程连接的权限
            if (remoteMqttIsConnecting || remoteIsConnected)
            if (RemoteMqttIsConnecting || remoteIsConnected)
            {
                return;
            }
@@ -232,7 +234,7 @@
                try
                {
                    #region 初始化远程Mqtt
                    RemoteMqttIsConnecting = true;
                    RemoteMqttClient = new MqttFactory().CreateMqttClient();
@@ -244,48 +246,62 @@
                            try
                            {
                                var topic = e.ApplicationMessage.Topic;
                                MainPage.Log($"收到mqtt主题:{topic}");
                                //一端口主题处理
                                if (DB_ResidenceData.Instance.GatewayType == 0 && !DB_ResidenceData.Instance.CheckWhetherGatewayIdIsNull())
                                {
                                    if (topic == $"/BusGateWayToClient/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/NotifyBusGateWayInfoChange")
                                    {
                                        //网关上线,需要更新aeskey
                                        //收到网关上线消息主题
                                        ReceiveNotifyBusGateWayInfoChange();
                                        return;
                                    }
                                    else if (topic == $"/BusGateWayToClient/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/NotifyGateWayOffline")
                                    {
                                        //网关掉线
                                        //----第二步:读取账号下面的网关列表
                                        ReceiveNotifyGateWayOffline();
                                        return;
                                    }
                                    else if (topic == $"/BusGateWayToClient/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/Common/CheckGateway")
                                    {
                                        var ss = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                                        //ReceiveCheckGateway(ss);
                                        return;
                                    }
                                }
                                if (topic == $"/BusGateWayToClient/{UserInfo.Current.ID}" + PushNotifySqueeze)
                                {
                                    var mMes = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                                    //新挤下线主题方案 收到挤下线主题
                                    ReceiveNotifySqueezeAsync(mMes);
                                }
                                else if (topic == $"/BusGateWayToClient/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/NotifyBusGateWayInfoChange")
                                {//网关上线,需要更新aeskey
                                    //收到网关上线消息主题
                                    ReceiveNotifyBusGateWayInfoChange();
                                }
                                else if (topic == $"/BusGateWayToClient/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/NotifyGateWayOffline")
                                {//网关掉线
                                    //----第二步:读取账号下面的网关列表
                                    ReceiveNotifyGateWayOffline();
                                }
                                else if (topic == $"/BusGateWayToClient/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/Common/CheckGateway")
                                //A网关设备状态-包含涂鸦设备
                                else if (topic == $"/user/{DB_ResidenceData.Instance.CurrentRegion.RegionID}/app/thing/property/send")
                                {
                                    var ss = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                                    ReceiveCheckGateway(ss);
                                    var bytes = Securitys.EncryptionService.AesDecryptPayload(e.ApplicationMessage.Payload, tuyaEncryptKey);
                                    var revString = Encoding.UTF8.GetString(bytes);
                                    Control.Ins.UpdataFunctionStatus(revString, null,true);
                                }
                                //一端口数据解析
                                else
                                {
                                    SetGatewayOnlineResetCheck();
                                    if (Entity.DB_ResidenceData.residenceData.GatewayType == 0)
                                    {
                                        var packet = new Packet();
                                    //SetGatewayOnlineResetCheck();
                                    var bytes = Securitys.EncryptionService.AesDecryptPayload(e.ApplicationMessage.Payload, mqttEncryptKey);
                                    //bus数据解析
                                    var packet = new Packet();
                                        if (!string.IsNullOrEmpty(mqttEncryptKey))
                                        {
                                            packet.Bytes = Securitys.EncryptionService.AesDecryptPayload(e.ApplicationMessage.Payload, mqttEncryptKey);
                                        }
                                        else
                                        {
                                            packet.Bytes = e.ApplicationMessage.Payload;
                                        }
                                        packet.Manager();
                                    if (!string.IsNullOrEmpty(mqttEncryptKey))
                                    {
                                        packet.Bytes = Securitys.EncryptionService.AesDecryptPayload(e.ApplicationMessage.Payload, mqttEncryptKey);
                                    }
                                    else
                                    {
                                        //A协议数据处理
                                        packet.Bytes = e.ApplicationMessage.Payload;
                                    }
                                    packet.Manager();
                                }
                            }
                            catch { }
@@ -304,19 +320,15 @@
                    //(3)ConnectedHandler
                    if (RemoteMqttClient.ConnectedHandler == null)
                    {
                        RemoteMqttClient.UseConnectedHandler(async (e) => {
                        RemoteMqttClient.UseConnectedHandler(async (e) =>
                        {
                            IfNeedReadAllDeviceStatus = true;
                            Control.Ins.GatewayOnline_Cloud = true;
                            Utlis.WriteLine($"============>Mqtt远程连接成功");
                            SendPushSignOut();
                            //if (Control.Ins.IsRemote) {
                            //    //Utlis.ShowAppLinkStatus (AppLinkStatus.CloudLink);
                            //    MainPage.AddTip (Language.StringByID (SimpleControl.R.MyInternationalizationString.LinkSuccess));
                            //}
                        });
                    }
                    #endregion
                    //}
                    //(4)===========开始连接过程==========
                    //之前已经获取参数成功过
@@ -339,7 +351,7 @@
                finally
                {
                    //最终要释放连接状态
                    remoteMqttIsConnecting = false;
                    RemoteMqttIsConnecting = false;
                    Utlis.WriteLine($"StartCloudMqtt: 结束");
                }
@@ -369,7 +381,7 @@
        {
            try
            {
                if (MqttInfoConfig.Current.HomeGatewayInfo != null && MqttInfoConfig.Current.HomeGatewayInfo.mac == Entity.DB_ResidenceData.residenceData.residenceGatewayMAC)
                if (MqttInfoConfig.Current.HomeGatewayInfo != null && MqttInfoConfig.Current.HomeGatewayInfo.mac == Entity.DB_ResidenceData.Instance.residenceGatewayMAC)
                {
                    await MQTTConnectAsync();
                }
@@ -392,11 +404,6 @@
        /// <returns></returns>
        static async Task StartMQTTGetInfo()
        {
            if (!Control.Ins.IsRemote)
            {
                return;
            }
            await GetMqttInfoAndMQTTConnectAsync();
            ////--判断是当前是否分享的住宅
@@ -415,13 +422,9 @@
        /// </summary>
        static async Task MQTTConnectAsync()
        {
            if (!Control.Ins.IsRemote)
            {
                return;
            }
            if (MqttInfoConfig.Current.HomeGatewayInfo != null && MqttInfoConfig.Current.mMqttInfo != null)
            //if (MqttInfoConfig.Current.HomeGatewayInfo != null && MqttInfoConfig.Current.mMqttInfo != null)
            //没有网关情况下,也需要连接mqtt,涂鸦第三方设备不需要网关
            if (MqttInfoConfig.Current.mMqttInfo != null)
            {
                try
                {
@@ -439,7 +442,18 @@
                    MqttInfoConfig.Current.IfGetMqttInfoSuccess = true;
                    MqttInfoConfig.Current.Save();
                    mqttEncryptKey = MqttInfoConfig.Current.HomeGatewayInfo.aesKey;
                    //解密密钥规则:已现有的住宅ID为基准,从右边一一获取值,最后如果不够16位,则往右补零
                    string aesKey = string.Empty;
                    for (int i = DB_ResidenceData.Instance.CurrentRegion.RegionID.Length - 1; i >= 0; i--)
                    {
                        aesKey += DB_ResidenceData.Instance.CurrentRegion.RegionID[i].ToString();
                        if (aesKey.Length == 16) { break; }
                    }
                    aesKey = aesKey.PadRight(16, '0');
                    tuyaEncryptKey = aesKey;
                    var options1 = new MQTTnet.Client.Options.MqttClientOptionsBuilder()
                                        .WithClientId(clientId)
@@ -495,12 +509,11 @@
        {
            try
            {
                SetGatewayOnlineResetCheck();
                if (Control.Ins.IsRemote)
                //SetGatewayOnlineResetCheck();
                if (Control.Ins.GatewayOnline_Cloud)
                {
                    CheckIfNeedReadAllDeviceStatus();
                }
            }
            catch { }
        }
@@ -510,23 +523,33 @@
        /// </summary>
        static void ReceiveNotifyGateWayOffline()
        {
            if (Control.Ins.IsRemote)
            {
                Control.Ins.GatewayOnline = false;
            }
            Control.Ins.GatewayOnline_Cloud = false;
        }
        /// <summary>
        /// 收到挤下线推送
        /// </summary>
        static void ReceiveNotifySqueezeAsync(string mMes)
        {
            if (mMes == PushSignStr ) return;//是自己的登录推送不处理//或者当前不是远程链接状态
            //测试账号,不挤下线
            switch (UserInfo.Current.AccountString)
            {
                case "13415629083":
                case "18316120654":
                case "15622703419":
                case "18824864143":
                case "464027401@qq.com":
                case "2791308028@qq.com":
                case "13697499568":
                case "18666455392":
                case "13375012446":
                case "13602944661":
                case "18778381374":
                case "18316672920":
                    return;
            }
            if (mMes == PushSignStr) return;//是自己的登录推送不处理
            //断开远程连接
            Control.Ins.IsRemote = false;
            if (!UserInfo.Current.IsLogin)
            {
                return;
@@ -534,32 +557,39 @@
            DisConnectRemoteMqttClient("挤下线");
            UserInfo.Current.LastTime = DateTime.MinValue;
            UserInfo.Current.SaveUserInfo();
            Application.RunOnMainThread(() => {
                MainPage.GoLoginPage(UserInfo.Current);
            Application.RunOnMainThread(() =>
            {
                //弹窗提示被挤下线
                HDLCommon.Current.CheckLogout();
            });
            //UserInfo.Current.LastTime = DateTime.MinValue;
            //UserInfo.Current.SaveUserInfo();
            //Application.RunOnMainThread(() => {
            //    MainPage.GoLoginPage(UserInfo.Current);
            //    //弹窗提示被挤下线
            //});
            //2020-08-11 删除推送数据
            //HDLRequest.Current.PushserivceSignOut ();
        }
        /// <summary>
        /// 收到CheckGateway主题
        /// </summary>
        static void ReceiveCheckGateway(string mMes)
        {
            if (!Control.Ins.IsRemote) return;
        ///// <summary>
        ///// 收到CheckGateway主题
        ///// </summary>
        //static void ReceiveCheckGateway(string mMes)
        //{
        //    if (!Control.Ins.IsRemote) return;
            Utlis.WriteLine("ReceiveCheckGateway!");
        //    Utlis.WriteLine("ReceiveCheckGateway!");
            //CheckIfNeedReadAllDeviceStatus ();
        //    //CheckIfNeedReadAllDeviceStatus ();
            //var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePack>(mMes);
            Control.Ins.GatewayOnline = true;
        }
        //    //var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePack>(mMes);
        //    Control.Ins.GatewayOnline = true;
        //}
        /// <summary>
        /// 推送挤下线主题
@@ -578,8 +608,6 @@
        /// <returns></returns>
        public static async Task MqttRemoteSend(byte[] message, int optionType = 0)
        {
            //return;
            try
            {
                string topicName;
@@ -592,11 +620,6 @@
                            message = 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/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/Common/CheckGateway";
                        Utlis.WriteLine("CheckGateway");
                        await RemoteMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topicName, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce });
                        break;
                    case 4://发布新方案的挤下线主题
                        topicName = $"/BusGateWayToClient/{UserInfo.Current.ID}" + PushNotifySqueeze;
@@ -625,18 +648,28 @@
        /// 是否需要读取一次所有设备状态
        /// </summary>
        static bool IfNeedReadAllDeviceStatus = true;
        //public static bool IsGatewayOnline = true;
        /// <summary>
        /// 设置网关在线标志,并重置CheckGateway参数
        /// </summary>
        static void SetGatewayOnlineResetCheck()
        {
            if (Control.Ins.IsRemote)
            {
                Control.Ins.GatewayOnline = true;
            }
        }
        ///// <summary>
        ///// 设置网关在线标志,并重置CheckGateway参数
        ///// </summary>
        //static void SetGatewayOnlineResetCheck()
        //{
        //    if (Control.Ins.IsRemote)
        //    {
        //        if (!Control.Ins.GatewayOnline)
        //        {
        //            try
        //            {
        //                if (DB_ResidenceData.Instance.HomeGateway != null)
        //                {
        //                    DB_ResidenceData.Instance.HomeGateway.gatewayStatus = true;
        //                }
        //                Control.Ins.GatewayOnline = true;
        //            }
        //            catch { }
        //        }
        //    }
        //}
        /// <summary>
@@ -651,17 +684,18 @@
                MqttInfoConfig.Current.mMqttInfo = mqttInfoRequestResult_Obj;
                await MQTTConnectAsync();
                //1.判断是否绑定了网关,获取网关远程连接的加密KEY
                if (DB_ResidenceData.residenceData.CheckWhetherGatewayIsBound())
                //if (DB_ResidenceData.Instance.CheckWhetherGatewayIsBound())
                {
                    //2.找出是否存在匹配当前住宅的mac,存在再进行远程。
                    MqttInfoConfig.Current.HomeGatewayInfo = DB_ResidenceData.residenceData.HomeGateway;
                    MqttInfoConfig.Current.HomeGatewayInfo = DB_ResidenceData.Instance.HomeGateway;
                    //3.开始连接
                    await MQTTConnectAsync();
                }
                else
                {
                    Utlis.WriteLine("============>还没绑定网关");
                }
                //else
                //{
                //    Utlis.WriteLine("============>还没绑定网关");
                //    hadGateway = false;
                //}
            }
        }