wxr
2020-09-09 c3e1b733fc45bd9f0b88bfb560cfa87a270b079b
HDL_ON/DAL/Net/MqttCommon.cs
@@ -1,398 +1,196 @@
using System.Collections.Generic;
using System;
using MQTTnet.Client;
using System.Text;
using System.Security.Cryptography;
using MQTTnet;
using MQTTnet.Client.Options;
using System.Net.Sockets;
using System.Threading.Tasks;
//using System.Net;
//using Newtonsoft.Json.Linq;
//using HDL_ON.DAL;
//using Newtonsoft.Json;
namespace HDL_ON.DAL.Net
{
    public static class MqttCommon
    public class RemoteRequestParameters
    {
        public string RequestVersion;
        public int RequestSource;
        public string LoginAccessToken;
        public int RequestProtocolType;
        public int HdlGatewayGatewayType = 0;
        public bool IsRedirectSelectEmqServer = false;
        /// <summary>
        /// MqttClient
        /// 平台类型字符串
        /// </summary>
        public static IMqttClient mqttClient_A;
        public static string mqttClientIP;
        public static string mqttGatewayMAC;
        static bool remoteIsConnected;
        static bool onConnection = false;
        static MqttCommon()
        {
            InitMqtt();
        }
        /// <summary>
        /// 断开远程Mqtt的链接
        /// </summary>
        public static async Task DisConnectRemoteMqttClient(string s = "")
        {
            try
            {
                if (remoteIsConnected)
                {
                    remoteIsConnected = false;
                    System.Console.WriteLine($"Remote主动断开_{s}");
                    //await RemoteMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions { }, CancellationToken.None);
                    await mqttClient_A.DisconnectAsync();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"Remote断开通讯连接出异常:{e.Message}");
            }
        }
        static bool isSubscribeSuccess;
        static async Task SubscribeTopics()
        {
            if (remoteIsConnected && !isSubscribeSuccess)
            {
                try
                {
                    var Topic1 = $"/BusGateWayToApp/{mqttGatewayMAC}/Common/Json";
                    try
                    {
                        await mqttClient_A.SubscribeAsync(Topic1);
                    }
                    catch (Exception ex)
                    {
                        await DisConnectRemoteMqttClient(ex.Message);
                        await StartMqtt();
                        if (remoteIsConnected)
                        {
                            await mqttClient_A.SubscribeAsync(Topic1);
                        }
                    }
                }
                catch { }
            }
        }
        static void InitMqtt()
        {
            new System.Threading.Thread(async () => {
                while (true)
                {
                    try
                    {
                        System.Threading.Thread.Sleep(1000);
                        //if (!CommonPage.IsRemote)
                        //    continue;
                        if (remoteIsConnected)
                            continue;
                        await StartMqtt();
                        await SubscribeTopics();
                    }
                    catch { }
                }
            })
            { IsBackground = true }.Start();
        }
        public string PlatformStr;
        /// <summary>
        /// 启动A协议Mqtt
        /// 发布主题负载
        /// </summary>
        public static async Task StartMqtt()
        {
            try
            {
                if (remoteIsConnected)
                    return;
                if (onConnection)
                    return;
                onConnection = true;
                new System.Threading.Thread(async () =>
                {
                    if (remoteIsConnected)
                        return;
                    try
                    {
                        if (mqttClient_A == null)
                        {
                            mqttClient_A = new MqttFactory().CreateMqttClient();
                            mqttClient_A.UseApplicationMessageReceivedHandler(async e =>
                            {
                                var aesDecryptTopic = e.ApplicationMessage.Topic;
                                var aesDecryptPayload = e.ApplicationMessage.Payload;
                                MainPage.Log(aesDecryptTopic);
                                MainPage.Log($"Des Topic={aesDecryptTopic}");
                            });
        public string PublishPayloadJsonStr;
                            mqttClient_A.UseConnectedHandler(async (e) => {
                                MainPage.Log("mqtt connected !!");
                                onConnection = false;
                            });
                        }
                        try
                        {
                            int readCount = 0;
                            BusSocket.Stop();
                            System.Threading.Thread.Sleep(1000);
                            BusSocket.Start(6688);
                            System.Threading.Thread.Sleep(1000);
                            Control.ReadGatewayIPAddress();
                            while(true)
                            {
                                if (!string.IsNullOrEmpty(mqttClientIP))
                                {
                                    break;
                                }
                                else if (readCount > 10)
                                {
                                    onConnection = false;
                                    return;
                                }
                                else
                                {
                                    Control.ReadGatewayIPAddress();
                                    System.Threading.Thread.Sleep(200);
                                }
                            }
                            BusSocket.Stop();
                            System.Threading.Thread.Sleep(1000);
                            BusSocket.Start(6000);
                            System.Threading.Thread.Sleep(1000);
                            var options = new MqttClientOptionsBuilder()//MQTT连接参数填充
                                .WithClientId(Guid.NewGuid().ToString().Substring(0, 5))//客户端ID
                                .WithTcpServer(mqttClientIP, 1883)//MQTTServerIP.Text, Int32.Parse(MQTTServerPort.Text.ToString()))//TCP服务端  1883  ,即MQTT服务端
                                .WithCredentials("", "")//"", "")//凭证  帐号 密码
                                .WithCommunicationTimeout(new TimeSpan(0, 0, 60)) //重连超时时间,默认5s
                                .WithKeepAlivePeriod(new TimeSpan(0, 0, 15)) //保持连接时间,默认5s,心跳包
                                .Build();
                            await mqttClient_A.ConnectAsync(options);
                            remoteIsConnected = true;
                        }
                        catch { }
                    }
                    catch (Exception ex)
                    {
                    }
                    finally
                    {
                        onConnection = false;
                    }
                })
                { IsBackground = true }.Start();
            }
            catch (Exception ex)
            {
                MainPage.Log("============>" + ex.Message);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="message">附加数据包</param>
        /// <param name="optionType">操作类型:0=网关控制;1=订阅网关数据;2=订阅网关上线数据</param>
        /// <returns></returns>
        public static async Task MqttRemoteSend(byte[] message)
        {
            try
            {
                if (mqttClient_A == null || !mqttClient_A.IsConnected)
                {
                    await StartMqtt();
                }
                if (!mqttClient_A.IsConnected)
                {
                    return;
                }
                var topicName = $"/AppToBusGateWay/{mqttGatewayMAC}/Common/Json";
                var m = new MqttApplicationMessage { Topic = topicName, Payload = message, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce };
                await mqttClient_A?.PublishAsync(m);
            }
            catch (Exception e)
            {
            }
        }
        public string Mac = "";
        public string GroupName = "";
    }
}
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 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;
    //app自定义数据
    public string md5_mac_string;
    public string LoginAccessToken;
}
namespace Shared.Securitys
{
    public partial class EncryptionService
    public class MqttRemoteInfo
    {
        public List<RemoteMACInfo> pageData;
        #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;
            if (string.IsNullOrEmpty(key)) return pToEncrypt;
            //需要加密内容的明文流
            Byte[] toEncryptArray = Encoding.UTF8.GetBytes(pToEncrypt);
        public int pageIndex = 0;
        public int pageSize = 10;
        public int totalCount = 3;
        public int totalPages = 1;
        public bool hasPreviousPage = false;
        public bool hasNextPage = false;
    }
            //配置AES加密Key(密钥、向量、模式、填充)
            RijndaelManaged rm = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(key),
                IV = Encoding.UTF8.GetBytes(key),
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7
            };
    public class MqttInfo
    {
        public string connEmqDomainPort;
        public string connEmqClientId;
        public string connEmqUserName;
        public string connEmqPwd;
            //创建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)
        {
            if (string.IsNullOrEmpty(key)) return toEncryptArray;
            //配置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
        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;
        public string clientId;
        //app自定义数据
        public string md5_mac_string;
        public string LoginAccessToken;
    }
    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;
                if (string.IsNullOrEmpty(key)) return pToEncrypt;
                //需要加密内容的明文流
                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)
            {
                if (string.IsNullOrEmpty(key)) return toEncryptArray;
                //配置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
        }
    }
}