wei
2021-06-02 e13a9980ce617db1394a76944186c5d5bd595d5d
HDL_ON/DAL/Mqtt/MqttClient.cs
@@ -11,6 +11,7 @@
using HDL_ON.DriverLayer;
using HDL_ON.Entity;
using HDL_ON.UI;
using HDL_ON.DAL.Server;
namespace HDL_ON.DAL.Mqtt
{
@@ -71,11 +72,6 @@
                    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)
@@ -137,10 +133,13 @@
                {
                    try
                    {
                        System.Threading.Thread.Sleep(500);
                        //if (!Control.Ins.IsRemote) continue;
                        System.Threading.Thread.Sleep(2000);
                        //进入后台不处理
                        if (MainPage.IsEnterBackground) continue;
                        if (MqttInfoConfig.Current.HomeGatewayInfo == null)
                        {
                            continue;
                        }
                        await StartCloudMqtt();
                        await SubscribeTopics();
@@ -190,22 +189,52 @@
                    };
                    var topicAlinkStatus = new MqttTopicFilter()
                    {
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.RegionID}/app/thing/property/send",
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/property/send",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                    };
                    //App订阅红外宝 / 网关遥控器添加成功通知
                    var pirStatus = new MqttTopicFilter()
                    {
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/topo/found",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                    };
                    //App订阅遥控器自学按键学习成功通知
                    var pirStudy = new MqttTopicFilter()
                    {
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/event/irCodeStudyDone/up",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                    };
                    #region 数据更新推送主题
                    //appHomeRefresh:住宅数据刷新通知
                    var appHomeRefresh = new MqttTopicFilter()
                    {
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/event/appHomeRefresh/up",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                    };
                    //appRoomRefresh:房间数据刷新通知
                    var appRoomRefresh = new MqttTopicFilter()
                    {
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/event/appRoomRefresh/up",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                    };
                    //appDeviceRefresh:设备数据刷新通知
                    var appDeviceRefresh = new MqttTopicFilter()
                    {
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/event/appDeviceRefresh/up",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                    };
                    #endregion
                    Utlis.WriteLine("开始订阅!");
                    var result = await RemoteMqttClient.SubscribeAsync(new MqttTopicFilter[] {  topicFilterPush2, topicAlinkStatus });
                    var result = await RemoteMqttClient.SubscribeAsync(new MqttTopicFilter[] {
                        pirStatus,pirStudy,
                        appDeviceRefresh,appHomeRefresh,appRoomRefresh,
                        topicFilterPush2, topicAlinkStatus });
                    if (result.Items[0].ResultCode == MQTTnet.Client.Subscribing.MqttClientSubscribeResultCode.GrantedQoS0)
                    {
                        Control.Ins.GatewayOnline = true;
                        isSubscribeSuccess = true;
                        Utlis.WriteLine("订阅成功!");
                        if (MqttInfoConfig.Current.HomeGatewayInfo != null && MqttInfoConfig.Current.HomeGatewayInfo.mac == Entity.DB_ResidenceData.Instance.residenceGatewayMAC)
                        {
                            Control.Ins.IsRemote = true;
                        }
                        MqttRemoteSend(new byte[] { 0 }, 3);
                    }
                }
                catch (Exception ex)
@@ -229,6 +258,10 @@
            {
                return;
            }
            if (DB_ResidenceData.Instance.CurrentRegion == null || DB_ResidenceData.Instance.CurrentRegion.id == null)
            {
                return;
            }
            //追加:没有远程连接的权限
            if (RemoteMqttIsConnecting || remoteIsConnected)
@@ -238,7 +271,7 @@
            Utlis.WriteLine($"StartCloudMqtt: 开始");
            await Task.Factory.StartNew(async () => {
            await Task.Factory.StartNew((Func<Task>)(async () => {
                try
                {
                    #region 初始化远程Mqtt
@@ -250,11 +283,11 @@
                    if (RemoteMqttClient.ApplicationMessageReceivedHandler == null)
                    {
                        //处理接收到的数据
                        RemoteMqttClient.UseApplicationMessageReceivedHandler((e) => {
                        RemoteMqttClient.UseApplicationMessageReceivedHandler((Action<MqttApplicationMessageReceivedEventArgs>)((e) => {
                            try
                            {
                                var topic = e.ApplicationMessage.Topic;
                                MainPage.Log($"收到mqtt主题:{topic}");
                                //MainPage.Log($"收到mqtt主题:{topic}");
                                //一端口主题处理
                                if (DB_ResidenceData.Instance.GatewayType == 0 && !DB_ResidenceData.Instance.CheckWhetherGatewayIdIsNull())
                                {
@@ -275,9 +308,15 @@
                                    else if (topic == $"/BusGateWayToClient/{MqttInfoConfig.Current.HomeGatewayInfo.gatewayId}/Common/CheckGateway")
                                    {
                                        var ss = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                                        ReceiveCheckGateway(ss);
                                        //ReceiveCheckGateway(ss);
                                        return;
                                    }
                                }
                                //一些特殊的主题处理(为了执行速度,尽可能的别加耗时的操作 true:执行了特殊处理 false:没有执行特殊处理)
                                if (Stan.HdlCloudReceiveLogic.Current.CloudOverallMsgReceiveEx(topic, e.ApplicationMessage.Payload, mqttEncryptKey, tuyaEncryptKey) == true)
                                {
                                    return;
                                }
                                if (topic == $"/BusGateWayToClient/{UserInfo.Current.ID}" + PushNotifySqueeze)
@@ -286,18 +325,109 @@
                                    //新挤下线主题方案 收到挤下线主题
                                    ReceiveNotifySqueezeAsync(mMes);
                                }
                                //A网关设备状态-包含涂鸦设备
                                else if (topic == $"/user/{DB_ResidenceData.Instance.CurrentRegion.RegionID}/app/thing/property/send")
                                //App订阅红外宝/网关遥控器添加成功通知
                                else if (topic == $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/topo/found")
                                {
                                    var bytes = Securitys.EncryptionService.AesDecryptPayload(e.ApplicationMessage.Payload, tuyaEncryptKey);
                                    var revString = Encoding.UTF8.GetString(bytes);
                                    Control.Ins.UpdataFunctionStatus(revString, null);
                                    HDL_ON.UI.UI2.PersonalCenter.PirDevice.PirMethod.controldata = revString;
                                }
                                //App订阅遥控器自学按键学习成功通知
                                else if (topic == $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/event/irCodeStudyDone/up")
                                {
                                    var bytes = Securitys.EncryptionService.AesDecryptPayload(e.ApplicationMessage.Payload, tuyaEncryptKey);
                                    var revString = Encoding.UTF8.GetString(bytes);
                                    UI.UI2.PersonalCenter.PirDevice.PirMethod.buttondata = revString;
                                }
                                #region 数据更新推送主题
                                //appHomeRefresh:住宅数据刷新通知
                                else if (topic == $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/event/appHomeRefresh/up")
                                {
                                    MainPage.Log("住宅数据刷新通知");
                                    new HttpServerRequest().GetHomePager();
                                }
                                //appRoomRefresh:房间数据刷新通知
                                else if (topic == $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/event/appRoomRefresh/up")
                                {
                                    MainPage.Log("房间数据刷新通知");
                                    var roomResult = new HttpServerRequest().GetRoomList();
                                    if (roomResult.Code == StateCode.SUCCESS)
                                    {
                                        MainPage.Log($"读取房间信息成功");
                                        var revData = Newtonsoft.Json.JsonConvert.DeserializeObject<SpatialApiPack>(roomResult.Data.ToString());
                                        if (revData == null)
                                        {
                                            revData = new SpatialApiPack();
                                        }
                                        {
                                            SpatialInfo.CurrentSpatial.UpdateSpatialList(revData.list);
                                        }
                                    }
                                    else
                                    {
                                        MainPage.Log($"读取房间数据失败:Code:{roomResult.Code}; msg:{roomResult.message}");
                                    }
                                }
                                //appDeviceRefresh:设备数据刷新通知
                                else if (topic == $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/event/appDeviceRefresh/up")
                                {
                                    MainPage.Log("设备数据刷新通知");
                                    var deviceResult = new HttpServerRequest().GetDeviceList();
                                    if (deviceResult.Code == StateCode.SUCCESS)
                                    {
                                        MainPage.Log($"读取设备信息成功");
                                        var deviceList = Newtonsoft.Json.JsonConvert.DeserializeObject<DevcieApiPack>(deviceResult.Data.ToString());
                                        if (deviceList == null)
                                        {
                                            deviceList = new DevcieApiPack();
                                        }
                                        string delFile = "";
                                        if (FunctionList.List.GetDeviceFunctionList().Count > 0)
                                        {
                                            for (int i = 0; i < FunctionList.List.GetDeviceFunctionList().Count;)
                                            {
                                                var localFunction = FunctionList.List.GetDeviceFunctionList()[i];
                                                if (localFunction.Spk_Prefix == FunctionCategory.Music || string.IsNullOrEmpty(localFunction.Spk_Prefix))
                                                {
                                                    i++;
                                                    continue;
                                                }
                                                var newFunction = deviceList.list.Find((obj) => obj.deviceId == localFunction.deviceId);
                                                if (delFile == localFunction.savePath)
                                                {
                                                    i++;
                                                    continue;
                                                }
                                                delFile = localFunction.savePath;
                                                FunctionList.List.DeleteFunction(localFunction);
                                            }
                                        }
                                        //处理剩下的新增功能
                                        foreach (var newFunction in deviceList.list)
                                        {
                                            newFunction.SaveFunctionFile();
                                            FunctionList.List.IniFunctionList(newFunction.savePath);
                                        }
                                    }
                                    else
                                    {
                                        MainPage.Log($"读取云端设备数据失败:Code:{deviceResult.Code};  Msg:{deviceResult.message}");
                                    }
                                }
                                #endregion
                                //A网关设备状态-包含涂鸦设备
                                else if (topic == $"/user/{DB_ResidenceData.Instance.CurrentRegion.id}/app/thing/property/send")
                                {
                                    var bytes = Securitys.EncryptionService.AesDecryptPayload(e.ApplicationMessage.Payload, tuyaEncryptKey);
                                    var revString = Encoding.UTF8.GetString(bytes);
                                    Control.Ins.UpdataFunctionStatus(revString, null, true);
                                }
                                //一端口数据解析
                                else
                                {
                                    SetGatewayOnlineResetCheck();
                                    var bytes = Securitys.EncryptionService.AesDecryptPayload(e.ApplicationMessage.Payload, mqttEncryptKey);
                                    //SetGatewayOnlineResetCheck();
                                    //var bytes = Securitys.EncryptionService.AesDecryptPayload(e.ApplicationMessage.Payload, mqttEncryptKey);
                                    //bus数据解析
                                    var packet = new Packet();
@@ -313,7 +443,7 @@
                                }
                            }
                            catch { }
                        });
                        }));
                    }
                    //(2)DisconnectedHandler
@@ -331,6 +461,7 @@
                        RemoteMqttClient.UseConnectedHandler(async (e) =>
                        {
                            IfNeedReadAllDeviceStatus = true;
                            Control.Ins.GatewayOnline_Cloud = true;
                            Utlis.WriteLine($"============>Mqtt远程连接成功");
                            SendPushSignOut();
                        });
@@ -354,6 +485,8 @@
                catch (Exception ex)
                {
                    Utlis.WriteLine($"error:" + ex.Message);
                    //mqtt连接异常,清空本地mqtt信息,可能需要重新获取:wxr
                    MqttInfoConfig.Current.Refresh();
                }
                finally
                {
@@ -363,7 +496,7 @@
                    Utlis.WriteLine($"StartCloudMqtt: 结束");
                }
            });
            }));
        }
@@ -411,11 +544,6 @@
        /// <returns></returns>
        static async Task StartMQTTGetInfo()
        {
            //if (!Control.Ins.IsRemote)
            //{
            //    return;
            //}
            await GetMqttInfoAndMQTTConnectAsync();
            ////--判断是当前是否分享的住宅
@@ -434,12 +562,6 @@
        /// </summary>
        static async Task MQTTConnectAsync()
        {
            //if (!Control.Ins.IsRemote)
            //{
            //    return;
            //}
            //if (MqttInfoConfig.Current.HomeGatewayInfo != null && MqttInfoConfig.Current.mMqttInfo != null)
            //没有网关情况下,也需要连接mqtt,涂鸦第三方设备不需要网关
            if (MqttInfoConfig.Current.mMqttInfo != null)
@@ -461,16 +583,13 @@
                    MqttInfoConfig.Current.Save();
                    if (MqttInfoConfig.Current.HomeGatewayInfo == null)
                    {
                        MqttInfoConfig.Current.HomeGatewayInfo = new Server.HomeGatewayInfo();
                    }
                    mqttEncryptKey = MqttInfoConfig.Current.HomeGatewayInfo.aesKey;
                    //解密密钥规则:已现有的住宅ID为基准,从右边一一获取值,最后如果不够16位,则往右补零
                    string aesKey = string.Empty;
                    for (int i = DB_ResidenceData.Instance.CurrentRegion.RegionID.Length - 1; i >= 0; i--)
                    for (int i = DB_ResidenceData.Instance.CurrentRegion.id.Length - 1; i >= 0; i--)
                    {
                        aesKey += DB_ResidenceData.Instance.CurrentRegion.RegionID[i].ToString();
                        aesKey += DB_ResidenceData.Instance.CurrentRegion.id[i].ToString();
                        if (aesKey.Length == 16) { break; }
                    }
                    aesKey = aesKey.PadRight(16, '0');
@@ -509,6 +628,8 @@
                    //重新中心服务器获取参数标记
                    MqttInfoConfig.Current.IfGetMqttInfoSuccess = false;
                    Console.WriteLine("Connect error: " + ex.Message);
                    //mqtt连接异常,清空本地mqtt信息,可能需要重新获取:wxr
                    MqttInfoConfig.Current.Refresh();
                }
                finally
                {
@@ -530,12 +651,11 @@
        {
            try
            {
                SetGatewayOnlineResetCheck();
                if (Control.Ins.IsRemote)
                //SetGatewayOnlineResetCheck();
                if (Control.Ins.GatewayOnline_Cloud)
                {
                    CheckIfNeedReadAllDeviceStatus();
                }
            }
            catch { }
        }
@@ -545,22 +665,35 @@
        /// </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;//是自己的登录推送不处理
            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":
                case "15971583093":
                case "15626203746":
                    return;
            }
            //断开远程连接
            Control.Ins.IsRemote = false;
            if (!UserInfo.Current.IsLogin)
            {
                return;
@@ -587,20 +720,20 @@
            //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>
        /// 推送挤下线主题
@@ -632,11 +765,6 @@
                        }
                        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;
                        //message = Encoding.UTF8.GetBytes (PushSignStr);
@@ -665,27 +793,27 @@
        /// </summary>
        static bool IfNeedReadAllDeviceStatus = 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>
        ///// 设置网关在线标志,并重置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>
@@ -694,9 +822,12 @@
        /// <returns></returns>
        static async Task GetMqttInfoAndMQTTConnectAsync()
        {
            var mqttInfoRequestResult_Obj = new Server.HttpServerRequest().GetMqttRemoteInfo(GetRandomKey());
            var mqttInfoRequestResult_Obj = new HttpServerRequest().GetMqttRemoteInfo(GetRandomKey());
            if (mqttInfoRequestResult_Obj != null)
            {
                MainPage.Log($"获取mqtt info 成功 /r/n clientId:{mqttInfoRequestResult_Obj.clientId}/r/n passWord:{mqttInfoRequestResult_Obj.passWord} /r/n url:{mqttInfoRequestResult_Obj.url}/r/n userName:{mqttInfoRequestResult_Obj.userName}");
                MqttInfoConfig.Current.mMqttInfo = mqttInfoRequestResult_Obj;
                await MQTTConnectAsync();
                //1.判断是否绑定了网关,获取网关远程连接的加密KEY
@@ -865,4 +996,4 @@
    }
}
}