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
|
{
|
/// <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();
|
}
|
|
/// <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}");
|
});
|
|
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 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
|
{
|
|
#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
|
|
|
}
|
}
|