黄学彪
2019-11-28 3a26f6025130dcaae4aa82ea19b16ad902450eb8
ZigbeeApp/Shared/Phone/ZigBee/Device/ZbGateway.cs
@@ -3090,27 +3090,46 @@
        /// </summary>
        IMqttClient localMqttClient = new MqttFactory().CreateMqttClient();
        bool localMqttIsConnecting;
        public bool localIsConnected;
        /// <summary>
        /// 手机标识
        /// </summary>
        static Guid currentGuid = Guid.NewGuid();
        public async System.Threading.Tasks.Task SendAesKey()
        {
            if (PubKey != null)
            {
                IsEncry = false;
                var rsaString = ZigBee.Common.SecuritySet.RSAEncrypt(PubKey, Password);
                var resultVerityfy = await SendAesKeyAsync(rsaString);
                if (resultVerityfy == null)
                {
                    resultVerityfy = await SendAesKeyAsync(rsaString);
                }
                if (resultVerityfy != null && resultVerityfy.Result == 0)
                {
                    IsEncry = true;
                }
            }
        }
        public async System.Threading.Tasks.Task StartLocalMqtt(string brokerName)
        {
        {
            if (localMqttIsConnecting
                       || !Shared.Common.Config.Instance.IsLogin
                       || Shared.Common.Config.Instance.HomeId == ""
                       || localIsConnected)
            {
                return;
            }
            await System.Threading.Tasks.Task.Factory.StartNew(async () =>
            {
                try
                {
                    lock (localMqttClient)
                    {
                        if (localMqttIsConnecting
                        || !Shared.Common.Config.Instance.IsLogin
                        || Shared.Common.Config.Instance.HomeId == ""
                        || localMqttClient.IsConnected)
                        {
                            return;
                        }
                        //表示后面将进行连接
                        localMqttIsConnecting = true;
@@ -3129,10 +3148,11 @@
                        if (localMqttClient.DisconnectedHandler == null)
                        {
                            localMqttClient.UseDisconnectedHandler((e) =>
                            {
                                IsEncry = false;
                            localMqttClient.UseDisconnectedHandler(async (e) =>
                            {
                                DebugPrintLog($" 本地连接断开_网关IP:{brokerName}_网关是否加:{IsEncry}");
                                await DisConnectLocalMqttClient("StartLocalMqtt.DisconnectedHandler");
                                //await StartLocalMqtt("ReConnect");
                            });
                        }
                        if (localMqttClient.ConnectedHandler == null)
@@ -3141,33 +3161,44 @@
                            {
                                DebugPrintLog($" 本地连接成功_网关IP:{brokerName}_网关是否加:{IsEncry}_当前密码:{Password}");
                                IsRemote = false;
                                if (PubKey != null)
                                {
                                    var rsaString = ZigBee.Common.SecuritySet.RSAEncrypt(PubKey, Password);
                                    var resultVerityfy = await SendAesKeyAsync(rsaString);
                                    if (resultVerityfy == null)
                                    {
                                        resultVerityfy = await SendAesKeyAsync(rsaString);
                                    }
                                    if (resultVerityfy != null && resultVerityfy.Result == 0)
                                    {
                                        IsEncry = true;
                                    }
                                }
                                Shared.Phone.UserCenter.HdlGatewayLogic.Current.CheckGatewayByConnectChanged(Shared.Phone.UserCenter.GatewayConnectMode.WIFI);
                                System.Console.WriteLine($"当前是网关Wi-Fi在通讯_{System.DateTime.Now.ToString()}");
                            });
                        }
                    }
                    var options = new MQTTnet.Client.Options.MqttClientOptionsBuilder()
                                   .WithClientId(currentGuid.ToString())
               .WithTcpServer(brokerName, 1883)
               .WithKeepAlivePeriod(TimeSpan.FromSeconds(20))
               .WithCleanSession()
               .WithCredentials("", "")
               .Build();
                    await localMqttClient.ConnectAsync(options, CancellationToken.None);
                        }
                        var dateTime = DateTime.Now;
                        new System.Threading.Thread(async () =>
                        {
                            try
                            {
                                if (localMqttClient.Options == null)
                                {
                                    var options = new MQTTnet.Client.Options.MqttClientOptionsBuilder().WithClientId(currentGuid.ToString())
                       .WithTcpServer(brokerName, 1883)
                       .WithKeepAlivePeriod(TimeSpan.FromSeconds(20))
                       .WithCleanSession()
                        .WithCommunicationTimeout(TimeSpan.FromSeconds(4))
                       .WithCredentials("", "")
                       .Build();
                                    await localMqttClient.ConnectAsync(options, CancellationToken.None);
                                }
                                else
                                {
                                    await DisConnectLocalMqttClient("StartLocalMqtt");
                                    await localMqttClient.ReconnectAsync();
                                }
                                localIsConnected = true;
                                await SendAesKey();
                            }
                            catch { }
                            dateTime = DateTime.MinValue;
                        })
                        { IsBackground = true }.Start();
                        while (dateTime != DateTime.MinValue)
                        {
                            System.Threading.Thread.Sleep(100);
                        }
                    }
                }
                catch (Exception ex)
                {
@@ -3279,6 +3310,7 @@
        /// 远程MqttClient
        /// </summary>
        public static IMqttClient RemoteMqttClient= new MqttFactory().CreateMqttClient();
        static bool remoteIsConnected;
        private int IsLogin = 0;
        [Newtonsoft.Json.JsonIgnore]
        static Action actionTemp;
@@ -3288,22 +3320,21 @@
        /// </summary>
        /// <returns>The start.</returns>
        /// <param name="brokerName">Broker name.</param>
        public static async System.Threading.Tasks.Task StartCloudMqtt()
        {
        public static async System.Threading.Tasks.Task StartRemoteMqtt()
        {
            if (remoteMqttIsConnecting
                       || !Shared.Common.Config.Instance.IsLogin
                       || Shared.Common.Config.Instance.HomeId == ""
                       || remoteIsConnected)
            {
                return;
            }
            await System.Threading.Tasks.Task.Factory.StartNew(async () =>
            {
                try
                {
                    lock (RemoteMqttClient)
                    {
                        if (remoteMqttIsConnecting
                        || !Shared.Common.Config.Instance.IsLogin
                        || Shared.Common.Config.Instance.HomeId == ""
                        || RemoteMqttClient.IsConnected)
                        {
                            return;
                        }
                        //表示后面将进行连接
                        remoteMqttIsConnecting = true;
@@ -3323,9 +3354,11 @@
                        if (RemoteMqttClient.DisconnectedHandler == null)
                        {
                            RemoteMqttClient.UseDisconnectedHandler((e) =>
                            RemoteMqttClient.UseDisconnectedHandler(async (e) =>
                            {
                                DebugPrintLog($"远程连接断开");
                                await DisConnectRemoteMqttClient("StartRemoteMqtt.DisconnectedHandler");
                                await StartRemoteMqtt();
                            });
                        }
                        if (RemoteMqttClient.ConnectedHandler == null)
@@ -3406,18 +3439,20 @@
                                var connEmqDomainPorts = connEmqDomainPort.Replace("//", "").Split(':');
                                var domain = connEmqDomainPorts[1];
                                var port = connEmqDomainPorts[2];
                                var options = new MQTTnet.Client.Options.MqttClientOptionsBuilder()
                                    .WithClientId(connEmqClientId)
                .WithTcpServer(domain, int.Parse(port))
                .WithCredentials(connEmqUserName, connEmqPwd)
                .WithKeepAlivePeriod(TimeSpan.FromSeconds(20))
                .WithCleanSession()
                .Build();
                                await RemoteMqttClient.ConnectAsync(options);
                                var port = connEmqDomainPorts[2];
                                var options = new MQTTnet.Client.Options.MqttClientOptionsBuilder()
                               .WithClientId(connEmqClientId)
           .WithTcpServer(domain, int.Parse(port))
           .WithCredentials(connEmqUserName, connEmqPwd)
           .WithKeepAlivePeriod(TimeSpan.FromSeconds(20))
           .WithCleanSession()
           .WithCommunicationTimeout(TimeSpan.FromSeconds(6))
           .Build();
                                await DisConnectRemoteMqttClient("StartRemoteMqtt");
                                await RemoteMqttClient.ConnectAsync(options, CancellationToken.None);
                                remoteIsConnected = true;
                            }
                        }
                    }
@@ -3438,28 +3473,40 @@
        /// <summary>
        /// 断开服务器连接
        /// </summary>
        public async System.Threading.Tasks.Task DisConnect(string s)
        public async System.Threading.Tasks.Task DisConnectLocalMqttClient(string s)
        {
            try
            {
                DebugPrintLog($"主动断开_{s}");
                if (localMqttClient.IsConnected == true)
                if (localIsConnected)
                {
                    await localMqttClient.DisconnectAsync();
                }
                    localIsConnected = false;
                    DebugPrintLog($"Local主动断开_{s}");
                    await localMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions {  }, CancellationToken.None);
                }
            }
            catch (Exception ex)
            {
                DebugPrintLog($"断开通讯连接出异常:{ex.Message}");
                DebugPrintLog($"Local断开通讯连接出异常:{ex.Message}");
            }
        }
        /// <summary>
        /// 断开远程Mqtt的链接
        /// </summary>
        public static void DisRemoteMqttClientConnect()
        public static async System.Threading.Tasks.Task DisConnectRemoteMqttClient(string s="")
        {
            RemoteMqttClient.DisconnectAsync();
            try
            {
                if (remoteIsConnected)
                {
                    remoteIsConnected = false;
                    DebugPrintLog($"Remote主动断开_{s}");
                    await RemoteMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions { }, CancellationToken.None);
                }
            }
            catch(Exception e) {
                DebugPrintLog($"Remote断开通讯连接出异常:{e.Message}");
            }
        }
        #endregion
@@ -3492,35 +3539,35 @@
        /// </summary>
        async System.Threading.Tasks.Task SendRemoteMsg(string topicName, byte[] message, bool retain = false)
        {
            if (this.getGatewayBaseInfo?.gwID == null || !GateWayBaseInfomations.ContainsKey(this.getGatewayBaseInfo?.gwID))
            {
                return;
            }
            var gateWayBaseInfomation = GateWayBaseInfomations[this.getGatewayBaseInfo?.gwID];
            ////(1)生成[用户名:密码]
            //var userNameAndPwdStr = string.Concat(Shared.Common.Config.Instance.Guid, RemoteOperatorConsts.CAP_NUMBER, Shared.Common.Config.Instance.MD5PWD);
            //DebugPrintLog($"userNameAndPwdStr:{userNameAndPwdStr} ");
            ////(2)将(1)转成Base64字符串,生成格式[Base64(用户名:密码)]
            //var userNameAndPwdStrBaseSexFour = Convert.ToBase64String(ZigBee.Common.CommonInfo.EncodingUTF8.GetBytes(userNameAndPwdStr));
            ////(3)将(2)继续生成格式[Base64(用户名:密码):Timestamp]
            //var userNameAndPwdStrBaseSexFourAndTimestamp = string.Concat(userNameAndPwdStrBaseSexFour, RemoteOperatorConsts.CAP_NUMBER, CurrentTimeStamp.ToString());
            ////[Zigbee.Buspro]App/id(帐号Id)/Base64(DES[Base64(用户名:密码):Timestamp ]/网关唯一Id/转发给网关的主题/XX/XX
            ////(4)生成上报主题,主题模式需要为  /ZigbeeApp/id(主子调试帐号Id)/Base64(DES[Base64(用户名:密码):Timestamp ]/网关唯一Id/topicName "000204022022"   GateWayId  000204022022
            //var reportTopic = string.Format("/{0}/{1}/{2}/{3}/{4}", RemoteOperatorConsts.ZIGBEE_APP_STARTS_WITH, Shared.Common.Config.Instance.Guid, userNameAndPwdStrBaseSexFourAndTimestamp, this.getGatewayBaseInfo?.gwID, topicName);
            ////文件流不用加密
            //var topicEncStr = ZigBee.Common.SecuritySet.AesEncrypt(System.Text.Encoding.UTF8.GetBytes(reportTopic), gateWayBaseInfomation.AesKey);
            //topicEncStr = topicEncStr.Replace("/", "[[$-MQTT_TILT_SYMBOL_REPLACE-$]]").Replace("+", "[[$-MQTT_PLUS_SYMBOL_REPLACE-$]]");
            //message = System.Text.Encoding.UTF8.GetBytes(SecuritySet.AesEncrypt(message, gateWayBaseInfomation.AesKey));
            message = SecuritySet.AesEncryptBytes(message, gateWayBaseInfomation.AesKey);
            var topicEncStr = $"/ClientToZigbeeGateWay/{gateWayBaseInfomation.MacMark}/Common/{topicName}";
            //(6)构建Mqtt需要发布的数据包,发布给云端的MqttBroker
            if (RemoteMqttClient.IsConnected)
            {
                await RemoteMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topicEncStr, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce });
            try
            {
                if (this.getGatewayBaseInfo?.gwID == null || !GateWayBaseInfomations.ContainsKey(this.getGatewayBaseInfo?.gwID))
                {
                    return;
                }
                var gateWayBaseInfomation = GateWayBaseInfomations[this.getGatewayBaseInfo?.gwID];
                message = SecuritySet.AesEncryptBytes(message, gateWayBaseInfomation.AesKey);
                var topicEncStr = $"/ClientToZigbeeGateWay/{gateWayBaseInfomation.MacMark}/Common/{topicName}";
                //(6)构建Mqtt需要发布的数据包,发布给云端的MqttBroker
                if (remoteIsConnected)
                {
                    try
                    {
                        await RemoteMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topicEncStr, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce });
                    }
                    catch (Exception e)
                    {
                        await DisConnectRemoteMqttClient(e.Message);
                        await StartRemoteMqtt();
                        if (remoteIsConnected)
                        {
                            await RemoteMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topicEncStr, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce });
                        }
                    }
                }
            }
            catch
            {
            }
        }
@@ -3547,12 +3594,8 @@
                }
                else
                {
                    DebugPrintLog($"局域网——发送到网关的主题:{topic}_发送到网关的数据:{System.Text.Encoding.UTF8.GetString(message)}_当前网关{CurrentGateWayId}");
                    if (!localMqttClient.IsConnected)
                    {
                        await StartLocalMqtt(getGatewayBaseInfo.IpAddress);
                    }
                    DebugPrintLog($"局域网——发送到网关的主题:{topic}_发送到网关的数据:{System.Text.Encoding.UTF8.GetString(message)}_当前网关{CurrentGateWayId} 是否加密:{IsEncry}");
                    if (IsEncry)
                    {
                        //文件流不用加密
@@ -3561,11 +3604,24 @@
                            topic = ZigBee.Common.SecuritySet.AesEncrypt(System.Text.Encoding.UTF8.GetBytes(topic), Password);
                            topic = topic.Replace("/", "[[$-MQTT_TILT_SYMBOL_REPLACE-$]]").Replace("+", "[[$-MQTT_PLUS_SYMBOL_REPLACE-$]]");
                            message = System.Text.Encoding.UTF8.GetBytes(SecuritySet.AesEncrypt(message, password));
                            DebugPrintLog($"局域网——发送到网关的主题(秘文):{topic}_当前秘钥{Password}_发送到网关的数据(秘文):{System.Text.Encoding.UTF8.GetString(message)}_当前网关{CurrentGateWayId}_{System.DateTime.Now.ToString()}");
                        }
                    }
                    await localMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topic, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce, Retain = retain });
                    }
                    if (localIsConnected)
                    {
                        try
                        {
                            await localMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topic, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce, Retain = retain });
                        }
                        catch(Exception e)
                        {
                            await DisConnectLocalMqttClient(e.Message);
                            await StartLocalMqtt("ReConnect");
                            if (localIsConnected)
                            {
                                await localMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topic, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce, Retain = retain });
                            }
                        }
                    }
                }
            }
            catch (Exception ex)