public static MqttStatus Subscribe(Guid key, string topic, string gxproc, int qos) { try { if (string.IsNullOrEmpty(gxproc)) { throw new ArgumentNullException(nameof(gxproc), "GeneXus procedure parameter cannot be null"); } string fullPath = gxproc; if (!Path.IsPathRooted(gxproc)) { string fileName = $"a{gxproc}.dll"; string baseDir = !string.IsNullOrEmpty(AppDomain.CurrentDomain.RelativeSearchPath) ? AppDomain.CurrentDomain.RelativeSearchPath : AppDomain.CurrentDomain.BaseDirectory; fullPath = Path.Combine(baseDir, fileName); } if (!File.Exists(fullPath)) { throw new FileNotFoundException($"File not found at {fullPath}", fullPath); } MqttClient mqtt = GetClient(key); if (topic.Contains("*") || topic.Contains("+") || topic.Contains("#")) { if (!mqtt.m_config.AllowWildcardsInTopicFilters) { throw new InvalidDataException("Wildcards not allowed for this instance."); } } MqttClientSubscribeOptions options = new MqttClientSubscribeOptions { //TopicFilters = new List<MqttTopicFilter> { new MqttTopicFilter() { Topic = topic, QualityOfServiceLevel = (MQTTnet.Protocol.MqttQualityOfServiceLevel)Enum.ToObject(typeof(MQTTnet.Protocol.MqttQualityOfServiceLevel), qos) } }, TopicFilters = new List <TopicFilter> { new TopicFilter() { Topic = topic, QualityOfServiceLevel = (MQTTnet.Protocol.MqttQualityOfServiceLevel)Enum.ToObject(typeof(MQTTnet.Protocol.MqttQualityOfServiceLevel), qos) } }, UserProperties = new List <MqttUserProperty> { new MqttUserProperty("gxrocedure", $"{{\"gxrocedure\":\"{gxproc}\"}}") } }; if (mqtt.m_mqttClient.ApplicationMessageReceivedHandler == null) { mqtt.m_mqttClient.UseApplicationMessageReceivedHandler(mqtt.ProcessMessage); } MqttClientSubscribeResult result = mqtt.m_mqttClient.SubscribeAsync(options).GetAwaiter().GetResult(); mqtt.AddTopic(topic, fullPath); // GetClient s_topicProcs[GetProcKey(mqtt, topic)] = gxproc; } catch (Exception ex) { return(MqttStatus.Fail(key, ex)); } return(MqttStatus.Success(key)); }
public static MqttStatus Connect(string url, MqttConfig config) { Guid key = Guid.NewGuid(); try { #if DEBUG IMqttClient client = new MqttFactory().CreateMqttClient(new ConsoleLogger()); #else IMqttClient client = new MqttFactory().CreateMqttClient(); #endif var b = new MqttClientOptionsBuilder() .WithTcpServer(url, config.Port) .WithKeepAlivePeriod(TimeSpan.FromSeconds(config.KeepAlive)) .WithMaximumPacketSize(Convert.ToUInt32(config.BufferSize)) .WithCommunicationTimeout(TimeSpan.FromSeconds(config.ConnectionTimeout)) .WithCleanSession(config.CleanSession); if (config.SessionExpiryInterval > 0) { b = b.WithSessionExpiryInterval((uint)config.SessionExpiryInterval); } if (!string.IsNullOrEmpty(config.ClientId)) { b = b.WithClientId(config.ClientId); } if (!config.SSLConnection) { b = b.WithCredentials(config.UserName, config.Password); } switch (config.ProtocolVersion) { case 310: b = b.WithProtocolVersion(MqttProtocolVersion.V310); break; case 311: b = b.WithProtocolVersion(MqttProtocolVersion.V311); break; case 500: b = b.WithProtocolVersion(MqttProtocolVersion.V500); break; default: throw new InvalidDataException("Invalid protocol versions. Valid versions are 310, 311 or 500"); } if (config.SSLConnection) { string base64CACert = RSAKeys.GetPlainBase64(config.CAcertificate); X509Certificate2 caCert = new X509Certificate2(Convert.FromBase64String(base64CACert)); byte[] caBytes = caCert.Export(X509ContentType.Cert); string base64Client = RSAKeys.GetPlainBase64(config.ClientCertificate); X509Certificate2 cliCert = new X509Certificate2(Convert.FromBase64String(base64Client), config.ClientCerificatePassphrase); cliCert = cliCert.CopyWithPrivateKey(RSAKeys.ImportPrivateKey(config.PrivateKey, new PasswordFinder(config.ClientCerificatePassphrase))); byte[] cliBytes = cliCert.Export(X509ContentType.Pfx); try { var tls = new MqttClientOptionsBuilderTlsParameters { SslProtocol = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls, UseTls = true, AllowUntrustedCertificates = true, IgnoreCertificateChainErrors = true, IgnoreCertificateRevocationErrors = true, Certificates = new List <X509Certificate>() { caCert, cliCert }, //CertificateValidationHandler = context => true CertificateValidationCallback = (certificate, chain, sslError, opts) => true }; b = b.WithTls(tls); } finally { caCert.Dispose(); cliCert.Dispose(); } } client.UseDisconnectedHandler(async e => { try { if (Connections.ContainsKey(key)) { await Task.Delay(TimeSpan.FromSeconds(config.AutoReconnectDelay)); MqttClientAuthenticateResult reconnectResult = await client.ConnectAsync(b.Build()); SubscribePreviousConnection(key, reconnectResult); } } catch { Connections.Remove(key); client.Dispose(); } }); MqttClientAuthenticateResult result = client.ConnectAsync(b.Build()).GetAwaiter().GetResult(); MqttClient mqtt = new MqttClient(client, config); Connections[key] = mqtt; SubscribePreviousConnection(key, result); } catch (Exception ex) { return(MqttStatus.Fail(Guid.Empty, ex)); } return(MqttStatus.Success(key)); }