Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        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));
        }