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 { /// /// MqttClient /// public static IMqttClient mqttClient_A; public static string mqttClientIP; public static string mqttGatewayMAC; static bool remoteIsConnected; static bool onConnection = false; static MqttCommon() { InitMqtt(); } /// /// 断开远程Mqtt的链接 /// 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(); } /// /// 启动A协议Mqtt /// 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}"); }); 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); } } /// /// /// /// 附加数据包 /// 操作类型:0=网关控制;1=订阅网关数据;2=订阅网关上线数据 /// 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 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 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 { #region 加密 /// /// 加密主题为Base64 /// /// /// /// 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); } /// /// 加密负载为二进制流 /// /// /// /// 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 解密 /// /// 解密主题数据 /// /// /// /// 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); } /// /// 采用Aes解密负载数据 /// /// /// /// 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 } }