/* 更新了EMQ连接方式 */ using System; using MQTTnet.Client; using System.Threading.Tasks; using Shared; using Shared.SimpleControl; using MQTTnet; using System.Text; using System.Security.Cryptography; using System.Collections.Generic; namespace SmartHome { public static class MqttCommon { /// /// 是否提示 远程连接的错误信息 /// public static bool IfDEBUG = false; /// /// 加密通讯KEY /// static string mqttEncryptKey = ""; //static string checkGatewayTopicBase64 = ""; /// /// 挤下线主题 /// static readonly string PushNotifySqueeze = "/Push/NotifySqueeze"; ///// ///// 挤下线主题 ///// //static readonly string TopicToApp = "/Push/NotifySqueeze"; /// /// 是否获取过密钥 /// static bool isGetGatewaySecretKey = false; /// /// 随机Key /// static string RandomKey = ""; static string GetRandomKey () { if (string.IsNullOrEmpty (RandomKey)) { //随机2位字符串 RandomKey = Utlis.CreateRandomString (2); } return RandomKey; } /// /// 远程MqttClient /// public static IMqttClient RemoteMqttClient = new MqttFactory ().CreateMqttClient (); /// /// 推送标识 /// static string PushSignStr = System.DateTime.Now.Ticks.ToString (); /// /// 断开远程Mqtt的链接 /// public static async System.Threading.Tasks.Task DisConnectRemoteMqttClient (string s = "") { try { if (remoteIsConnected) { remoteIsConnected = false; isSubscribeSuccess = false; Shared.Utlis.WriteLine ($"Remote主动断开_{s}"); //await RemoteMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions { }, CancellationToken.None); await RemoteMqttClient.DisconnectAsync (); if (CommonPage.IsRemote) { //不是无网络 if (UserConfig.Instance.internetStatus != 0) { Utlis.ShowAppLinkStatus (AppLinkStatus.CloudUnlink); } } } } catch (Exception e) { Shared.Utlis.WriteLine ($"Remote断开通讯连接出异常:{e.Message}"); } } /// /// 断开远程Mqtt的链接 /// static async Task DisConnectRemoteMqttClientWhenStart (string s = "") { try { //if (remoteIsConnected) { remoteIsConnected = false; isSubscribeSuccess = false; Shared.Utlis.WriteLine ($"RemoteStart主动断开_{s}"); await RemoteMqttClient.DisconnectAsync (); //} } catch (Exception e) { Shared.Utlis.WriteLine ($"RemoteStart断开通讯连接出异常:{e.Message}"); } } /// /// 断开mqtt连接 /// /// 断开原因 /// 是否需要去中心服务器 重新获取参数 /// public static async Task DisConnectRemote (string s = "", bool reset = true) { if (reset) { bNeedStartTip = true; bNeedConnectTip = true; CommonConfig.Current.IfGetMqttInfoSuccess = false; isGetGatewaySecretKey = false;//获取密钥标记为false } await DisConnectRemoteMqttClient (s); } //static DateTime dateTime = DateTime.MinValue; /// /// 外网的MQTT是否正在连接 /// public static bool remoteMqttIsConnecting; static bool remoteIsConnected; static MqttCommon () { InitMqtt (); } public static bool IsInitMqtt = false; ///// ///// 测试 ///// 定时发送 000E ///// ///// //static void InitCheckGateway () //{ // new System.Threading.Thread (async () => { // while (true) { // try { // if (!CommonPage.IsRemote) { // if (GatewayCommon != null) { // Control.ControlBytesSend (Command.ReadRemark, GatewayCommon.SubnetID, GatewayCommon.DeviceID, new byte [] { }); // Console.WriteLine ("发送000E "); // } // } // System.Threading.Thread.Sleep (55000); // } catch { } // } // }) { IsBackground = true }.Start (); //} //static Thread MQTTThread; //static void InitMqtt () //{ // remoteMqttIsConnecting = false; // if (MQTTThread != null) // MQTTThread.Abort (); // MQTTThread = new System.Threading.Thread (async () => { // while (true) { // try { // System.Threading.Thread.Sleep (200); // //if (!MainPage.LoginUser.IsLogin) { // // continue; // //} // if (!CommonPage.IsRemote) continue; // await StartCloudMqtt (); // await SubscribeTopics (); // } catch { } // } // }) { IsBackground = true }; // MQTTThread.Start (); //} static void InitMqtt () { new System.Threading.Thread (async () => { while (true) { try { System.Threading.Thread.Sleep (500); //if (!MainPage.LoginUser.IsLogin) { // continue; //} if (!CommonPage.IsRemote) continue; if (Control.IsEnterBackground) continue; await StartCloudMqtt (); await SubscribeTopics (); } catch { } } }) { IsBackground = true }.Start (); } /// /// 初始化状态 /// public static void InitState () { IfNeedReadAllDeviceStatus = true; bNeedStartTip = true; bNeedConnectTip = true; IsGatewayOnline = false; StartCloudMqtt (); } static bool isSubscribeSuccess; static async Task SubscribeTopics () { if (remoteIsConnected && !isSubscribeSuccess) { try { //var topicFilterPush = new TopicFilter { QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce, // Topic = $"/BusGateWayToClient/{CommonConfig.Instance.CurRemoteMACInfo.clientId}/Push/NotifySqueeze" }; //2020-05-14 订阅主题质量改为0 var topicFilterBusGateWayToClient = new MqttTopicFilter () { Topic = $"/BusGateWayToClient/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/#", QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce //QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce }; var topicFilterPush2 = new MqttTopicFilter { Topic = $"/BusGateWayToClient/{MainPage.LoginUser.ID}/#", QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce, //QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce }; //当设备MQTT报文加密密钥发生变更时,云端通过该主题通知其他客户端刷新密钥,其它和该网关交互的客户端自行订阅该主题,该主题包不加密 var topicFilterPush3 = new MqttTopicFilter { Topic = $"/user/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/custom/mqtt/secret/change", QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce, }; Utlis.WriteLine ("开始订阅!"); var result = await RemoteMqttClient.SubscribeAsync (new MqttTopicFilter [] { topicFilterBusGateWayToClient, topicFilterPush2, topicFilterPush3 }); if (result.Items [0].ResultCode == MQTTnet.Client.Subscribing.MqttClientSubscribeResultCode.GrantedQoS0) { isSubscribeSuccess = true; Utlis.WriteLine ("订阅成功!"); MqttRemoteSend (new byte [] { 0 }, 3); //读取搜索网关,判断网关是否在线 CheckGatewaysIfOnline (); ////连接成功后检测是否需要通过远程获取Key //CheckIfNeedGetLocalPasswordFromRemote (); } } catch (Exception ex) { Console.WriteLine ("订阅catch:" + ex.Message.ToString ()); } } } static DateTime mFlagDateTime; //static readonly object SendLocker = new object (); /// /// 启动远程Mqtt /// public static async Task StartCloudMqtt () { if (UserConfig.Instance.internetStatus == 0) { return; } if (!MainPage.LoginUser.IsLogin) { return; } //追加:没有远程连接的权限 if (remoteMqttIsConnecting || remoteIsConnected) { return; } //lock (SendLocker) { // remoteMqttIsConnecting = true; //} remoteMqttIsConnecting = true; #if DEBUG Shared.Utlis.WriteLine ($"StartCloudMqtt: 开始"); #endif await Task.Factory.StartNew (async () => { try { //lock (RemoteMqttClient) { // //表示后面将进行连接 // remoteMqttIsConnecting = true; #region 初始化远程Mqtt RemoteMqttClient = new MqttFactory ().CreateMqttClient (); //(1)当[连接云端的Mqtt成功后]或者[以及后面App通过云端Mqtt转发数据给网关成功后],处理接收到云端数据包响应时在mqttServerClient_ApplicationMessageReceived这个方法处理 if (RemoteMqttClient.ApplicationMessageReceivedHandler == null) { RemoteMqttClient.UseApplicationMessageReceivedHandler ((e) => { try { var topic = e.ApplicationMessage.Topic; if (topic == $"/BusGateWayToClient/{MainPage.LoginUser.ID}" + PushNotifySqueeze) { var mMes = CommonPage.MyEncodingUTF8.GetString (e.ApplicationMessage.Payload); //新挤下线主题方案 收到挤下线主题 ReceiveNotifySqueezeAsync (mMes); } else if (topic == $"/BusGateWayToClient/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/NotifyBusGateWayInfoChange") {//网关上线,需要更新aeskey //收到网关上线消息主题 ReceiveNotifyBusGateWayInfoChange (); } else if (topic == $"/user/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/custom/mqtt/secret/change") {//设备密钥更新通知,需要更新aeskey //设备密钥更新通知 HDLUtils.WriteLine ("设备密钥更新通知"); isGetGatewaySecretKey = false;//获取密钥标记为false GetGatewaySecretKey (); } else if (topic == $"/BusGateWayToClient/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/NotifyGateWayOffline") {//网关掉线 //----第二步:读取账号下面的网关列表 ReceiveNotifyGateWayOffline (); } else if (topic == $"/BusGateWayToClient/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/Common/CheckGateway") { var ss = CommonPage.MyEncodingUTF8.GetString (e.ApplicationMessage.Payload); ReceiveCheckGateway (ss); } else { SetGatewayOnlineResetCheck (); var packet = new Packet (); if (!string.IsNullOrEmpty (mqttEncryptKey)) { packet.Bytes = Shared.Securitys.EncryptionService.AesDecryptPayload (e.ApplicationMessage.Payload, mqttEncryptKey); } else { packet.Bytes = e.ApplicationMessage.Payload; } packet.IsLocal = false; packet.Manager (); } } catch { } }); } //(2)DisconnectedHandler if (RemoteMqttClient.DisconnectedHandler == null) { RemoteMqttClient.UseDisconnectedHandler (async (e) => { Shared.Utlis.WriteLine ($"远程连接断开"); isSubscribeSuccess = false; await DisConnectRemoteMqttClient ("UseDisconnectedHandler"); }); } //(3)ConnectedHandler if (RemoteMqttClient.ConnectedHandler == null) { RemoteMqttClient.UseConnectedHandler (async (e) => { IfNeedReadAllDeviceStatus = true; bNeedStartTip = true;// bNeedConnectTip = true; Shared.Utlis.WriteLine ($"============>Mqtt远程连接成功"); SendPushSignOut (); //if (CommonPage.IsRemote) { // //Utlis.ShowAppLinkStatus (AppLinkStatus.CloudLink); // MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LinkSuccess)); //} }); } #endregion //} //(4)===========开始连接过程========== //4.1 如果没获取过密钥则重新获取一次, 获取一次最新的密钥 if (isGetGatewaySecretKey || GetGatewaySecretKey ()) { //之前已经获取参数成功过 if (CommonConfig.Current.IfGetMqttInfoSuccess) { //判断是否需要重新获取 await CheckMQTTConnectAsync (); } else { //开始获取远程连接参数 await StartMQTTGetInfo (); } } } catch (Exception ex) { Shared.Utlis.WriteLine ($"error:" + ex.Message); if (IfDEBUG) { MainPage.ShowAlertOnMainThread ("error: " + ex.Message); } } finally { //最终要释放连接状态 remoteMqttIsConnecting = false; //lock (SendLocker) { // remoteMqttIsConnecting = false; //} //连接成功才关闭Loading if (remoteIsConnected) { MainPage.LoadingTipHide (); ERRORCount = 0; } else { ERRORCount++; //每5次重新提示一次 if (ERRORCount > 5) { ERRORCount = 0; MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.RemoteFailure)); MainPage.LoadingTipHide (); } } #if DEBUG Shared.Utlis.WriteLine ($"StartCloudMqtt: 结束"); #endif } }); } //static bool /// /// 检查网关是否在线线程 /// static System.Threading.Thread CheckGatewaysThead; /// /// 网关对象 /// public static Common GatewayCommon; /// /// 检查网关是否在线 /// static void CheckGatewaysIfOnline () { if (GatewayCommon == null) return; try { //提示搜索网关中 MainPage.LoadingTipShow (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.CheckingGatewayIsOnline)); if (CheckGatewaysThead != null) CheckGatewaysThead.Abort (); CheckGatewaysThead = new System.Threading.Thread (() => { var returnBytes = Control.ControlBytesSendHasReturn (Command.ReadGateway, GatewayCommon.SubnetID, GatewayCommon.DeviceID, new byte [] { (byte)new Random ().Next (255), (byte)new Random ().Next (255) }); //隐藏提示 MainPage.LoadingTipHide (); if (CommonPage.IsRemote) { if (returnBytes == null) { Application.RunOnMainThread (() => { IsGatewayOnline = false; Utlis.ShowAppLinkStatus (AppLinkStatus.CloudOffline); MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.RemoteFailedGatewayOffline)); //发送一次CheckGateway主题 MqttRemoteSend (new byte [] { 0 }, 3); }); } else { MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LinkSuccess)); IsGatewayOnline = true; Utlis.ShowAppLinkStatus (AppLinkStatus.CloudLink); Console.WriteLine ("ReadGateway success"); CheckIfNeedReadAllDeviceStatus (); } } }) { IsBackground = true }; CheckGatewaysThead.Start (); } catch { } } /// /// 检测是否需要发送刷新获取所有设备的命令 /// static void CheckIfNeedReadAllDeviceStatus () { if (IfNeedReadAllDeviceStatus) { Utlis.WriteLine ("ReadAllDeviceStatus"); IfNeedReadAllDeviceStatus = false; Shared.SimpleControl.Phone.UserMiddle.ReadAllDeviceStatus (); } } //连接错误次数统计 static int ERRORCount = 0; /// /// 是否需要提示 /// static bool bNeedConnectTip = true; /// /// 从开始到连接成功,只提示1次 /// static bool bNeedStartTip = true; /// /// 正在获取连接参数... /// static void ShowStartTip () { if (bNeedStartTip) { bNeedStartTip = false; if (CommonPage.IsRemote) { MainPage.LoadingTipShow (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GettingRemoteConnectionInfo)); } } //if (CommonPage.IsRemote) { // //MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GettingRemoteConnectionInfo)); // MainPage.LoadingTipShow (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GettingRemoteConnectionInfo)); //} } /// /// 检测之前获取的Mac与当前住宅MAC是否一致 不一致从新获取 /// /// static async Task CheckMQTTConnectAsync () { try { if (CommonConfig.Current.HomeGatewayInfo != null && CommonConfig.Current.HomeGatewayInfo.mac == UserConfig.Instance.GatewayMAC) { await MQTTConnectAsync (); } else { //Mac 变化了重新获取参数 await StartMQTTGetInfo (); } } catch { CommonConfig.Current.IfGetMqttInfoSuccess = false; } } /// /// 开始获取Mqtt 远程参数 /// /// static async Task StartMQTTGetInfo () { ShowStartTip (); if (!CommonPage.IsRemote) { return; } await GetMqttInfoAndMQTTConnectAsync (); ////--判断是当前是否分享的住宅 //if (!UserConfig.Instance.CurrentRegion.IsOthreShare) { // //主账号获取MQTT 远程链接信息,并连接 // await GetMqttInfoAndMQTTConnectAsync (); //} else { // //如果是分享过来的住宅 走下面流程 // //--第一步:获取当前住分享宅网关信息并连接MQTT // await GetSingleHomeGatewayPaggerAndMQTTConnectAsync (); //} } /// /// 连接MQTT /// static async Task MQTTConnectAsync () { if (!CommonPage.IsRemote) { return; } if (CommonConfig.Current.HomeGatewayInfo != null && CommonConfig.Current.mMqttInfo != null) { if (bNeedConnectTip) { bNeedConnectTip = false; MainPage.LoadingTipShow (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GetSuccessfullyStartConnecting)); } try { var url = CommonConfig.Current.mMqttInfo.url; //url = HttpUtil.GetProxyEMQUrl (url); //#if DEBUG // url = HttpUtil.GetProxyEMQUrl (url); //#endif var clientId = CommonConfig.Current.mMqttInfo.clientId; var username = CommonConfig.Current.mMqttInfo.userName; var passwordRemote = CommonConfig.Current.mMqttInfo.passWord; //获取参数成功,保存到本地并标记为true CommonConfig.Current.IfGetMqttInfoSuccess = true; CommonConfig.Current.Save (); mqttEncryptKey = CommonConfig.Current.HomeGatewayInfo.aesKey; var options1 = new MQTTnet.Client.Options.MqttClientOptionsBuilder () .WithClientId (clientId) .WithTcpServer (url.Split (':') [1].Substring ("//".Length), int.Parse (url.Split (':') [2])) .WithCredentials (username, passwordRemote) .WithCleanSession () .WithProtocolVersion (MQTTnet.Formatter.MqttProtocolVersion.V311) .WithCommunicationTimeout (new TimeSpan (0, 0, 10)) //.WithCommunicationTimeout (new TimeSpan (0, 0, 5)) //.WithCommunicationTimeout (new TimeSpan (0, 1, 0)) .Build (); await DisConnectRemoteMqttClient ("StartRemoteMqtt"); var mResult = await RemoteMqttClient.ConnectAsync (options1); if (mResult.ResultCode == MQTTnet.Client.Connecting.MqttClientConnectResultCode.Success) { remoteIsConnected = true; IsDisConnectingWithSendCatch = false; UnsupportedProtocolVersionCount = 0; } else { //重新中心服务器获取参数标记 CommonConfig.Current.IfGetMqttInfoSuccess = false; } } catch (Exception ex) { if (ex.Message == MqttCommunicationTimedOutException) { Console.WriteLine ("Connect error TimedOut: " + ex.Message); } else { //重新中心服务器获取参数标记 CommonConfig.Current.IfGetMqttInfoSuccess = false; Console.WriteLine ("Connect error: " + ex.Message); } //Console.WriteLine ("Connect error: " + ex.Message); if (IfDEBUG) { MainPage.ShowAlertOnMainThread ("Connect error: " + ex.Message); } } finally { } } else { CommonConfig.Current.IfGetMqttInfoSuccess = false; } } static int UnsupportedProtocolVersionCount = 0; static readonly string MqttCommunicationTimedOutException = "Exception of type 'MQTTnet.Exceptions.MqttCommunicationTimedOutException' was thrown."; // static readonly string UnsupportedProtocolVersion = "Connecting with MQTT server failed (UnsupportedProtocolVersion)."; /// /// 收到网关上线消息 /// static void ReceiveNotifyBusGateWayInfoChange () { try { SetGatewayOnlineResetCheck (); if (CommonPage.IsRemote) { //#if DEBUG MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GatewayLoginOnline)); //#endif CheckIfNeedReadAllDeviceStatus (); } } catch { } } /// /// 收到网关掉线信息 /// static void ReceiveNotifyGateWayOffline () { Shared.Utlis.WriteLine ("============>Mqtt GateWayOffline"); IsGatewayOnline = false; if (CommonPage.IsRemote) { Utlis.ShowAppLinkStatus (AppLinkStatus.CloudOffline); MainPage.AddTip (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.GatewayOffline)); } } /// /// 收到挤下线推送 /// static void ReceiveNotifySqueezeAsync (string mMes) { if (mMes == PushSignStr) return;//是自己的登录推送不处理 //断开远程连接 CommonPage.IsRemote = false; if (!MainPage.LoginUser.IsLogin) { return; } DisConnectRemoteMqttClient ("挤下线"); MainPage.LoginUser.LastTime = DateTime.MinValue; MainPage.LoginUser.SaveUserInfo (); Room.Lists.Clear (); Application.RunOnMainThread (() => { Utlis.ShowAppLinkStatus (AppLinkStatus.WiFi); new Shared.SimpleControl.Phone.AccountLogin (MainPage.LoginUser.AccountString, "").Show (); SharedMethod.SharedMethod.CurPageLayout = null; //CommonPage.IsRemote = false; MainPage.LoadingTipHide (); MainPage.Loading.Hide (); new Alert (Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.Tip), Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.LoggedOnOtherDevices), Language.StringByID (Shared.SimpleControl.R.MyInternationalizationString.Close)).Show (); }); //2020-08-11 删除推送数据 //HDLRequest.Current.PushserivceSignOut (); //#if HDL // if (!String.IsNullOrEmpty (MainPage.LoginUser.AllVisionRegisterDevUserNameGuid)) { // com.freeview.global.Video.Logout (); // }///BusGateWayToClient/320c1fea-1866-4708-8277-e2321a4dd236/NotifyGateWayInfoChange //#endif } /// /// 收到CheckGateway主题 /// static void ReceiveCheckGateway (string mMes) { if (!CommonPage.IsRemote) return; Utlis.WriteLine ("ReceiveCheckGateway!"); SetGatewayOnlineResetCheck (); } /// /// 推送挤下线主题 /// static void SendPushSignOut () { #if DEBUG return; #endif byte [] message = CommonPage.MyEncodingUTF8.GetBytes (PushSignStr); MqttRemoteSend (message, 4); } /// /// /// /// 附加数据包 /// 操作类型:0=网关控制;1=订阅网关数据;2=订阅网关上线数据 /// public static async Task MqttRemoteSend (byte [] message, int optionType = 0) { //return; try { string topicName; switch (optionType) { case 0: topicName = $"/ClientToBusGateWay/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/Common/ON"; if (!string.IsNullOrEmpty (mqttEncryptKey)) { //Utlis.WriteLine ("mqttEncryptKey:" + mqttEncryptKey); message = Shared.Securitys.EncryptionService.AesEncryptPayload (message, mqttEncryptKey); } await RemoteMqttClient.PublishAsync (new MqttApplicationMessage { Topic = topicName, Payload = message, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce }); break; case 3: topicName = $"/ClientToBusGateWay/{CommonConfig.Current.HomeGatewayInfo.gatewayId}/Common/CheckGateway"; Shared.Utlis.WriteLine ("CheckGateway"); await RemoteMqttClient.PublishAsync (new MqttApplicationMessage { Topic = topicName, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce }); break; case 4://发布新方案的挤下线主题 topicName = $"/BusGateWayToClient/{MainPage.LoginUser.ID}" + PushNotifySqueeze; //message = CommonPage.MyEncodingUTF8.GetBytes (PushSignStr); await RemoteMqttClient.PublishAsync (new MqttApplicationMessage { Topic = topicName, Payload = message, Retain = false, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce }); break; } } catch (Exception e) { //Utlis.WriteLine ($"============>Mqtt MqttRemoteSend catch"); if (!IsDisConnectingWithSendCatch) { IsDisConnectingWithSendCatch = true; await DisConnectRemoteMqttClient ("SendCatch"); } } } /// /// SendCatch 后执行一次断开操作 /// static bool IsDisConnectingWithSendCatch = false; /// /// 是否需要读取一次所有设备状态 /// static bool IfNeedReadAllDeviceStatus = true; public static bool IsGatewayOnline = true; //static int CheckGatewayCount = 0; //static DateTime mCheckGatewayTime; /// /// 设置网关在线标志,并重置CheckGateway参数 /// static void SetGatewayOnlineResetCheck () { //mCheckGatewayTime = DateTime.Now; //CheckGatewayCount = 0; if (CommonPage.IsRemote) { if (!IsGatewayOnline) { IsGatewayOnline = true; Utlis.ShowAppLinkStatus (AppLinkStatus.CloudLink); } } } /// /// 主账号获取MQTT 远程链接信息,并连接 /// /// static async Task GetMqttInfoAndMQTTConnectAsync () { var mqttInfoRequestResult_Obj = HttpServerRequest.Current.GetMqttRemoteInfo (GetRandomKey ()); if (mqttInfoRequestResult_Obj != null) { CommonConfig.Current.mMqttInfo = mqttInfoRequestResult_Obj; if (UserConfig.Instance.CheckHomeGatewaysNotEmpty ()) { //----第二步找出是否存在匹配当前住宅的mac,存在再进行远程。 CommonConfig.Current.HomeGatewayInfo = UserConfig.Instance.HomeGateway; if (CommonConfig.Current.HomeGatewayInfo != null) { //----第三步 开始连接 await MQTTConnectAsync (); } } else { Utlis.WriteLine ("============>还没绑定网关"); } } else { Utlis.WriteLine ("============>MqttInfo null"); } } /// /// 设备密钥更新通知,重新拿密钥 /// /// static bool GetGatewaySecretKey () { bool isSuccess = false; try { if (string.IsNullOrEmpty (UserConfig.Instance.CurrentRegion.Id)) return false; var nowhomeId = UserConfig.Instance.CurrentRegion.Id; var requestJson = HttpUtil.GetSignRequestJson (new HomeIdObj () { homeId = nowhomeId }); var revertObj = HttpUtil.RequestHttpsPostFroHome (NewAPI.API_POST_GetGatewayList, requestJson); if (revertObj.Code == StateCode.SUCCESS) { var mHomeGatewayRes = Newtonsoft.Json.JsonConvert.DeserializeObject> (revertObj.Data.ToString ()); if (nowhomeId == UserConfig.Instance.CurrentRegion.Id) { if (mHomeGatewayRes != null) { if (mHomeGatewayRes.Count > 0) { //只取第一个住宅 var info = mHomeGatewayRes [0]; UserConfig.Instance.HomeGateway = info; UserConfig.Instance.SaveUserConfig (); CommonConfig.Current.HomeGatewayInfo = info; //更新网关信息和加密Key mqttEncryptKey = info.aesKey; CommonConfig.Current.Save (); isSuccess = true; isGetGatewaySecretKey = true;//获取密钥标记为true } else { //打印错误 HDLUtils.WriteLine ("gateway is not bound"); } } } } else { //打印错误 HDLUtils.WriteLine ("Failed to get gateway info"); } return isSuccess; } catch { //return ""; return isSuccess; } } } } public class MqttInfo { /// /// /// public string url; /// /// /// public string clientId; /// /// /// public string userName; /// /// /// public string passWord; } 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 } }