/// <summary> /// Connect the client to the AR. The given options suit the testcases but have to be reviewed for a production environment regarding reconnecting for example. /// </summary> /// <param name="mqttClient">-</param> /// <param name="onboardResponse">-</param> /// <returns>No dedicated response.</returns> public static async Task ConnectMqttClient(IMqttClient mqttClient, OnboardResponse onboardResponse) { var tlsParameters = new MqttClientOptionsBuilderTlsParameters { Certificates = new[] { ReadRootCertificates(), ReadClientCertificate(onboardResponse) }, UseTls = true }; var options = new MqttClientOptionsBuilder() .WithClientId(onboardResponse.ConnectionCriteria.ClientId) .WithTcpServer(onboardResponse.ConnectionCriteria.Host, int.Parse(onboardResponse.ConnectionCriteria.Port)) .WithTls(tlsParameters) .WithCommunicationTimeout(TimeSpan.FromSeconds(20)) .Build(); await mqttClient.ConnectAsync(options); }
private IMqttClientOptions GetMqttOption(string clientId) { var builder = new MqttClientOptionsBuilder() .WithProtocolVersion(MqttProtocolVersion.V311) .WithKeepAlivePeriod(TimeSpan.FromSeconds(5)) .WithCommunicationTimeout(TimeSpan.FromSeconds(15)) .WithClientId(clientId) // this message will be sent to all clients // subscribed to <clientId>/status topic // if this client gets disconnected .WithWillMessage(new MqttApplicationMessage { Payload = Encoding.UTF8.GetBytes("disconnected"), Topic = String.Format("/{0}/status", clientId), Retain = true, QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce }); // TODO: ? // .WithCleanSession(); if (usingWebSockets) { builder.WithWebSocketServer(endPoint.Address + ":" + endPoint.Port + "/mqtt"); } else { builder.WithTcpServer(endPoint.Address, endPoint.Port); } if (networkCredential != null) { builder.WithCredentials(networkCredential.UserName, networkCredential.Password); } if (useSsl) { var tlsParameters = new MqttClientOptionsBuilderTlsParameters { UseTls = true }; builder.WithTls(tlsParameters); } return(builder.Build()); }
public void Start(string certPath) { X509Certificate2 certificate = new X509Certificate2(certPath); List <byte[]> certificates = new List <byte[]>(); certificates.Add(certificate.Export(X509ContentType.SerializedCert)); //setup connection options MqttClientOptionsBuilderTlsParameters tlsOptions = new MqttClientOptionsBuilderTlsParameters { Certificates = certificates, SslProtocol = SslProtocols.Tls12, UseTls = true }; tlsOptions.CertificateValidationCallback += CertificateValidationCallback; // Create TCP based options using the builder. var options = new MqttClientOptionsBuilder() .WithClientId($"Test_C#_Client_{Guid.NewGuid()}") .WithTcpServer(MqttServer, MqttPort) .WithTls(tlsOptions) .WithCleanSession() .WithKeepAlivePeriod(TimeSpan.FromSeconds(90)) .WithKeepAliveSendInterval(TimeSpan.FromSeconds(60)) .Build(); var factory = new MqttFactory(); mqttClient = factory.CreateMqttClient(); mqttClient.UseApplicationMessageReceivedHandler(DataHandler); mqttClient.UseConnectedHandler(ConnectedHandler); mqttClient.UseDisconnectedHandler(DisconnectedHandler); Console.WriteLine($"Connecting to mqtt.cloud.yandex.net..."); mqttClient.ConnectAsync(options, CancellationToken.None); }
private static int _iLastUpdateThreshold = 5; // Minutes public static async void StartMQTT(string strMQTTServer, bool bMQTTTLS, string strClientId, string strUser, string strPassword, MessageHandler messageHandler) { IManagedMqttClientOptions options; MqttClientOptionsBuilder clientOptions; MqttClientOptionsBuilderTlsParameters optionsTLS; int iPort = 0; string[] strMQTTServerArray; string strMQTTBroker; Logging.WriteDebugLog("MQTT.StartMQTT()"); if (strMQTTServer == null || strMQTTServer == "") { return; } _timerMQTT = new Timer(Update, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30)); _strClientId = strClientId; _messageHandler = messageHandler; if (strMQTTServer.Contains(":")) { strMQTTServerArray = strMQTTServer.Split(new char[] { ':' }); if (strMQTTServerArray.Length != 2) { Logging.WriteDebugLog("MQTT.StartMQTT() MQTTBroker field has incorrect syntax (host or host:port)"); return; } if (!int.TryParse(strMQTTServerArray[1], out iPort) || iPort == 0) { Logging.WriteDebugLog("MQTT.StartMQTT() MQTTBroker field has incorrect syntax - port not non-zero numeric (host or host:port)"); return; } if (strMQTTServerArray[0].Length == 0) { Logging.WriteDebugLog("MQTT.StartMQTT() MQTTBroker field has incorrect syntax - missing host (host or host:port)"); return; } strMQTTBroker = strMQTTServerArray[0]; Logging.WriteDebugLog("MQTT.StartMQTT() Host: {0}, Port: {1}", strMQTTBroker, iPort); } else { strMQTTBroker = strMQTTServer; Logging.WriteDebugLog("MQTT.StartMQTT() Host: {0}", strMQTTBroker); } clientOptions = new MqttClientOptionsBuilder().WithClientId(_strClientId).WithTcpServer(strMQTTBroker, (iPort == 0 ? null : iPort)); if (strUser != "") { clientOptions = clientOptions.WithCredentials(strUser, strPassword); } if (bMQTTTLS) { optionsTLS = new MqttClientOptionsBuilderTlsParameters { IgnoreCertificateChainErrors = true, UseTls = true, IgnoreCertificateRevocationErrors = true, AllowUntrustedCertificates = true, SslProtocol = System.Security.Authentication.SslProtocols.Tls12 }; clientOptions = clientOptions.WithTls(optionsTLS); } options = new ManagedMqttClientOptionsBuilder().WithAutoReconnectDelay(TimeSpan.FromSeconds(5)).WithClientOptions(clientOptions.Build()).Build(); _mqtt = new MqttFactory().CreateManagedMqttClient(); _mqtt.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(MessageProcessor); await _mqtt.StartAsync(options); }
public static async Task RunAsync() { // MqttNetConsoleLogger.ForwardToConsole(); // For most of these connections to work, set output target to Net5.0. #if NET5_0_OR_GREATER // TLS13 is only available in Net5.0 var unsafeTls13 = new MqttClientOptionsBuilderTlsParameters { UseTls = true, SslProtocol = SslProtocols.Tls13, // Don't use this in production code. This handler simply allows any invalid certificate to work. CertificateValidationHandler = w => true }; #endif // Also defining TLS12 for servers that don't seem no to support TLS13. var unsafeTls12 = new MqttClientOptionsBuilderTlsParameters { UseTls = true, SslProtocol = SslProtocols.Tls12, // Don't use this in production code. This handler simply allows any invalid certificate to work. CertificateValidationHandler = w => true }; // mqtt.eclipseprojects.io await ExecuteTestAsync("mqtt.eclipseprojects.io TCP", new MqttClientOptionsBuilder().WithTcpServer("mqtt.eclipseprojects.io", 1883) .WithProtocolVersion(MqttProtocolVersion.V311).Build()); await ExecuteTestAsync("mqtt.eclipseprojects.io WS", new MqttClientOptionsBuilder().WithWebSocketServer("mqtt.eclipseprojects.io:80/mqtt") .WithProtocolVersion(MqttProtocolVersion.V311).Build()); #if NET5_0_OR_GREATER await ExecuteTestAsync("mqtt.eclipseprojects.io WS TLS13", new MqttClientOptionsBuilder().WithWebSocketServer("mqtt.eclipseprojects.io:443/mqtt") .WithProtocolVersion(MqttProtocolVersion.V311).WithTls(unsafeTls13).Build()); #endif // test.mosquitto.org await ExecuteTestAsync("test.mosquitto.org TCP", new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 1883) .WithProtocolVersion(MqttProtocolVersion.V311).Build()); await ExecuteTestAsync("test.mosquitto.org TCP - Authenticated", new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 1884) .WithCredentials("rw", "readwrite") .WithProtocolVersion(MqttProtocolVersion.V311).Build()); await ExecuteTestAsync("test.mosquitto.org TCP TLS12", new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 8883) .WithProtocolVersion(MqttProtocolVersion.V311).WithTls(unsafeTls12).Build()); #if NET5_0_OR_GREATER await ExecuteTestAsync("test.mosquitto.org TCP TLS13", new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 8883) .WithProtocolVersion(MqttProtocolVersion.V311).WithTls(unsafeTls13).Build()); #endif await ExecuteTestAsync("test.mosquitto.org TCP TLS12 - Authenticated", new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 8885) .WithCredentials("rw", "readwrite") .WithProtocolVersion(MqttProtocolVersion.V311).WithTls(unsafeTls12).Build()); await ExecuteTestAsync("test.mosquitto.org WS", new MqttClientOptionsBuilder().WithWebSocketServer("test.mosquitto.org:8080/mqtt") .WithProtocolVersion(MqttProtocolVersion.V311).Build()); await ExecuteTestAsync("test.mosquitto.org WS TLS12", new MqttClientOptionsBuilder().WithWebSocketServer("test.mosquitto.org:8081/mqtt") .WithProtocolVersion(MqttProtocolVersion.V311).WithTls(unsafeTls12).Build()); // broker.emqx.io await ExecuteTestAsync("broker.emqx.io TCP", new MqttClientOptionsBuilder().WithTcpServer("broker.emqx.io", 1883) .WithProtocolVersion(MqttProtocolVersion.V311).Build()); await ExecuteTestAsync("broker.emqx.io TCP TLS12", new MqttClientOptionsBuilder().WithTcpServer("broker.emqx.io", 8883) .WithProtocolVersion(MqttProtocolVersion.V311).WithTls(unsafeTls12).Build()); #if NET5_0_OR_GREATER await ExecuteTestAsync("broker.emqx.io TCP TLS13", new MqttClientOptionsBuilder().WithTcpServer("broker.emqx.io", 8883) .WithProtocolVersion(MqttProtocolVersion.V311).WithTls(unsafeTls13).Build()); #endif await ExecuteTestAsync("broker.emqx.io WS", new MqttClientOptionsBuilder().WithWebSocketServer("broker.emqx.io:8083/mqtt") .WithProtocolVersion(MqttProtocolVersion.V311).Build()); await ExecuteTestAsync("broker.emqx.io WS TLS12", new MqttClientOptionsBuilder().WithWebSocketServer("broker.emqx.io:8084/mqtt") .WithProtocolVersion(MqttProtocolVersion.V311).WithTls(unsafeTls12).Build()); // broker.hivemq.com await ExecuteTestAsync("broker.hivemq.com TCP", new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com", 1883) .WithProtocolVersion(MqttProtocolVersion.V311).Build()); await ExecuteTestAsync("broker.hivemq.com WS", new MqttClientOptionsBuilder().WithWebSocketServer("broker.hivemq.com:8000/mqtt") .WithProtocolVersion(MqttProtocolVersion.V311).Build()); // mqtt.swifitch.cz: Does not seem to operate any more // cloudmqtt.com: Cannot test because it does not offer a free plan any more. Write("Finished.", ConsoleColor.White); Console.ReadLine(); }
public MqttClientOptionsBuilder WithTls(MqttClientOptionsBuilderTlsParameters parameters) { _tlsParameters = parameters ?? throw new ArgumentNullException(nameof(parameters)); return(this); }
private MqttClientOptionsBuilder CreateOptionsBuilder(ClientCredentials credentials = null) { MqttClientOptionsBuilder clientOptionsBuilder = new MqttClientOptionsBuilder(); MqttClientOptionsBuilderTlsParameters tlsParameters = null; string hostName = Settings.Client.BrokerHostname; int portNum = Settings.Client.BrokerPort; //check if broker endpoint for local connections is defined in environment, only possible for connections without credentials if (credentials == null) { string brokerEndpoint = Environment.GetEnvironmentVariable("GE_BROKER_CONNECTION_ENDPOINT"); if (!string.IsNullOrEmpty(brokerEndpoint)) { string[] tokens = brokerEndpoint.Split(':'); if (tokens.Length == 2) { hostName = tokens[0]; portNum = Convert.ToInt32(tokens[1], CultureInfo.InvariantCulture); } } } clientOptionsBuilder.WithCleanSession(); clientOptionsBuilder.WithClientId(ClientId); if (portNum == 443) { clientOptionsBuilder.WithWebSocketServer(hostName); } else { clientOptionsBuilder.WithTcpServer(hostName, portNum); } if (credentials != null) { if (credentials.HasCertificates()) { tlsParameters = new MqttClientOptionsBuilderTlsParameters { UseTls = true, AllowUntrustedCertificates = Settings.Client.AllowUntrustedCertificates, IgnoreCertificateChainErrors = Settings.Client.IgnoreCertificateChainErrors, IgnoreCertificateRevocationErrors = Settings.Client.IgnoreCertificateRevocationErrors, CertificateValidationHandler = CertificateValidationCallback, Certificates = credentials.ClientCertAndCaChain, SslProtocol = SslProtocols.Tls12 }; clientOptionsBuilder.WithTls(tlsParameters); } if (credentials.IsUserNameAndPasswordRequired()) { credentials.GetUserNameAndPassword(ClientId, out string username, out string password); clientOptionsBuilder.WithCredentials(username, password); } } // settings for connection timeout and MQTT kepp alive interval, given in seconds // (defaults in MQTTnet stack are CommunicationTimeout = 10 sec and KeepAlivePeriod = 15 sec., // see in MqttClientOptions.cs of MQTTnet) clientOptionsBuilder.WithCommunicationTimeout(new TimeSpan(0, 0, Settings.Client.CommunicationTimeout)); clientOptionsBuilder.WithKeepAlivePeriod(new TimeSpan(0, 0, Settings.Client.MqttKeepAlivePeriod)); return(clientOptionsBuilder); }
public async Task ConnectAsync(Options options, TaskCompletionSource <int> closedPromise) { if (options.Verbose) { MqttNetGlobalLogger.LogMessagePublished += (s, e) => { var trace = $">> [{e.LogMessage.Timestamp:O}] [{e.LogMessage.ThreadId}] [{e.LogMessage.Source}] [{e.LogMessage.Level}]: {e.LogMessage.Message}"; if (e.LogMessage.Exception != null) { trace += Environment.NewLine + e.LogMessage.Exception.ToString(); } Console.WriteLine(trace); }; } var factory = new MqttFactory(); var client = factory.CreateMqttClient(); client.UseApplicationMessageReceivedHandler(msg => this.HandleMessageAsync(msg)); var tlsOptions = new MqttClientOptionsBuilderTlsParameters(); tlsOptions.UseTls = true; var clientOptions = new MqttClientOptionsBuilder() .WithTcpServer(opt => opt.NoDelay = true) .WithClientId(options.ClientId) .WithTcpServer(options.Hostname, 8883) .WithTls(tlsOptions) .WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500) // .WithUserProperty("host", hostName) // normally it is not needed as SNI is added by most TLS implementations. .WithUserProperty("api-version", "2020-10-01-preview") .WithCommunicationTimeout(TimeSpan.FromSeconds(30)) .WithKeepAlivePeriod(TimeSpan.FromSeconds(300)) .WithCleanSession(false); // keep existing subscriptions if (string.IsNullOrEmpty(options.SasKey)) { tlsOptions.Certificates = new[] { new X509Certificate(options.ClientCertificatePath, options.ClientCertificatePassword) }; clientOptions.WithAuthentication("X509", null); } else { var at = DateTimeOffset.UtcNow; var atString = at.ToUnixTimeMilliseconds().ToString(); var expiry = at.AddMinutes(40); var expiryString = expiry.ToUnixTimeMilliseconds().ToString(); string toSign = $"{options.Hostname}\n{options.ClientId}\n{options.SasPolicy}\n{atString}\n{expiryString}\n"; var hmac = new HMACSHA256(Convert.FromBase64String(options.SasKey)); var sas = hmac.ComputeHash(Encoding.UTF8.GetBytes(toSign)); clientOptions .WithAuthentication("SAS", sas) .WithUserProperty("sas-at", atString) .WithUserProperty("sas-expiry", expiryString); if (!string.IsNullOrEmpty(options.SasPolicy)) { // include only if using SAS policy clientOptions.WithUserProperty("sas-policy", options.SasPolicy); } } // Set up disconnection handling: print out details and allow process to close client.UseDisconnectedHandler(disconnectArgs => { Console.WriteLine($"Disconnected: {disconnectArgs.ReasonCode}"); if (disconnectArgs.AuthenticateResult?.UserProperties != null) { foreach (var prop in disconnectArgs.AuthenticateResult.UserProperties) { Console.WriteLine($"{prop.Name}: {prop.Value}"); } } closedPromise.SetResult(1); }); try { // once connection is established, we may start receiving messages based on subscriptions // from previous connections - better set client before connection. this.client = client; var connectResult = await client.ConnectAsync(clientOptions.Build(), CancellationToken.None); if (connectResult.ResultCode != MqttClientConnectResultCode.Success) { var status = GetStatus(connectResult.UserProperties)?.ToString("x4"); throw new Exception($"Connect failed. Status: {connectResult.ResultCode}; status: {status}"); } if (!connectResult.IsSessionPresent) { // only subscribe if haven't subscribed already. // This optimization only works of a single SUBSCRIBE is used to subscribe to everything at once or // if app keeps track of what has been successfully acknowledged by server. var subscribeResult = await client.SubscribeAsync( new MqttTopicFilter { Topic = "$iothub/methods/+", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce }, new MqttTopicFilter { Topic = "$iothub/commands", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce }, new MqttTopicFilter { Topic = "$iothub/twin/patch/desired", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce }); // make sure subscriptions were successful if (subscribeResult.Items.Count != 3 || subscribeResult.Items[0].ResultCode != MqttClientSubscribeResultCode.GrantedQoS0 || subscribeResult.Items[1].ResultCode != MqttClientSubscribeResultCode.GrantedQoS1 || subscribeResult.Items[2].ResultCode != MqttClientSubscribeResultCode.GrantedQoS0) { throw new ApplicationException("Failed to subscribe"); } } } catch (MqttConnectingFailedException ex) { Console.WriteLine($"Failed to connect, reason code: {ex.ResultCode}"); if (ex.Result?.UserProperties != null) { foreach (var prop in ex.Result.UserProperties) { Console.WriteLine($"{prop.Name}: {prop.Value}"); } } throw; } }
private void Start(string brokerUrl, int port, string clientId, string username, string password, X509Certificate2 serverRootCa, X509Certificate clientCertificate, string[] topics) { _brokerUrl = brokerUrl; _port = port; Topics = topics; _serverRootCa = serverRootCa; Logger.Instance.AppendLog(new LogRecord(DateTime.Now, new List <string> { $"Start MQTT Client..." }, LogRecordLevel.Info)); try { lock (_lockObject) { var optionsBuilder = new MqttClientOptionsBuilder() .WithClientId(clientId) .WithTcpServer(brokerUrl, port) .WithCleanSession() //.WithKeepAliveSendInterval(TimeSpan.FromSeconds(KeepAliveIntervalSec)) // Keep alive send interval .WithKeepAlivePeriod(TimeSpan.FromSeconds(KeepAliveIntervalSec * 1.5)); // Time after last keep alive when IoT Core will disconnect the client if (clientCertificate == null) { //auth by username and password optionsBuilder.WithCredentials(username, password); if (serverRootCa != null) { MqttClientOptionsBuilderTlsParameters tlsOptions = new MqttClientOptionsBuilderTlsParameters(); tlsOptions.UseTls = true; tlsOptions.AllowUntrustedCertificates = true; //tlsOptions.IgnoreCertificateChainErrors = true; //tlsOptions.IgnoreCertificateRevocationErrors = true; tlsOptions.CertificateValidationCallback += MqttClient_CertificateValidationCallback; optionsBuilder.WithTls(tlsOptions); Logger.Instance.AppendLog(new LogRecord(DateTime.Now, new List <string> { $"Setup connection with username and password over TLS" }, LogRecordLevel.Info)); } else { Logger.Instance.AppendLog(new LogRecord(DateTime.Now, new List <string> { $"Setup connection with username and password" }, LogRecordLevel.Info)); } } else { // Auth by client certificate List <X509Certificate> certificates = new List <X509Certificate>(); certificates.Add(clientCertificate); MqttClientOptionsBuilderTlsParameters tlsOptions = new MqttClientOptionsBuilderTlsParameters(); tlsOptions.Certificates = certificates; tlsOptions.UseTls = true; tlsOptions.AllowUntrustedCertificates = true; //tlsOptions.IgnoreCertificateChainErrors = true; //tlsOptions.IgnoreCertificateRevocationErrors = true; if (serverRootCa != null) { tlsOptions.AllowUntrustedCertificates = true; tlsOptions.CertificateValidationCallback += MqttClient_CertificateValidationCallback; Logger.Instance.AppendLog(new LogRecord(DateTime.Now, new List <string> { $"Setup connection with client and server certificate over TLS" }, LogRecordLevel.Info)); } else { Logger.Instance.AppendLog(new LogRecord(DateTime.Now, new List <string> { $"Setup connection with client certificate over TLC" }, LogRecordLevel.Info)); } optionsBuilder.WithTls(tlsOptions); } _options = optionsBuilder.Build(); while (true) { try { Logger.Instance.AppendLog(new LogRecord(DateTime.Now, new List <string> { $"Connecting to MQTT server ..." }, LogRecordLevel.Info)); _mqttClient.ConnectAsync(_options).Wait(new TimeSpan(Timeout)); break; } catch (Exception ex) { Logger.Instance.AppendLog(new LogRecord(DateTime.Now, new List <string> { $"Can't connect to MQTT server: {ex.Message}" }, LogRecordLevel.Error)); Thread.Sleep(Timeout); } } } } catch (Exception ex) { Logger.Instance.AppendLog(new LogRecord(DateTime.Now, new List <string> { $"MQTT Client start was failed: {ex.Message}" }, LogRecordLevel.Error)); } Logger.Instance.AppendLog(new LogRecord(DateTime.Now, new List <string> { $"MQTT Client started" }, LogRecordLevel.Info)); }
public static async void exec() { Console.WriteLine("Enter ClientID"); string ClientID = Console.ReadLine(); Console.WriteLine("Chat with:"); string Friend = Console.ReadLine(); IManagedMqttClient mqttClient = new MqttFactory().CreateManagedMqttClient(); try { MqttClientOptionsBuilderTlsParameters TlsOptions = new MqttClientOptionsBuilderTlsParameters { UseTls = false }; var options = new MqttClientOptionsBuilder() .WithClientId(Guid.NewGuid().ToString("N")) .WithTcpServer("localhost") .WithTls(TlsOptions); var moptions = new ManagedMqttClientOptionsBuilder() .WithAutoReconnectDelay(TimeSpan.FromSeconds(5)) .WithClientOptions(options) .Build(); await mqttClient.StartAsync(moptions); } catch (Exception ex) { throw ex; } mqttClient.ApplicationMessageReceived += (s, e) => { //Console.WriteLine("### RECEIVED APPLICATION MESSAGE ###"); Console.WriteLine($"{e.ApplicationMessage.Topic}: {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}"); //Console.WriteLine($"+ Payload = "); //Console.WriteLine($"+ QoS = {e.ApplicationMessage.QualityOfServiceLevel}"); //Console.WriteLine($"+ Retain = {e.ApplicationMessage.Retain}"); Console.WriteLine(); }; mqttClient.Connected += async(s, e) => { Console.WriteLine("### CONNECTED WITH SERVER ###"); // Subscribe to a topic await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"chat/{Friend}").Build()); Console.WriteLine("### SUBSCRIBED ###"); }; while (true) { string msg = Console.ReadLine(); var message = new MqttApplicationMessageBuilder() .WithTopic($"chat/{ClientID}") .WithPayload(msg) .Build(); await mqttClient.PublishAsync(message); } }
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)); }
/// <summary> /// Service Start action. Do not call this directly. /// </summary> /// <param name="cancellationToken">Cancelation token.</param> /// <returns>Awaitable <see cref="Task" />.</returns> public async Task StartAsync(CancellationToken cancellationToken = default) { _serviceLog.LogInformation("Service start initiated"); _stopping = false; // MQTT will message var willMessage = new MqttApplicationMessageBuilder() .WithTopic($"{TopicRoot}/connected") .WithPayload(((int)ConnectionStatus.Disconnected).ToString()) .WithAtLeastOnceQoS() .WithRetainFlag() .Build(); // MQTT client options var optionsBuilder = new MqttClientOptionsBuilder() .WithTcpServer(_brokerSettings.BrokerIp, _brokerSettings.BrokerPort) .WithClientId(MqttClientId.ToString()) .WithCleanSession() .WithWillMessage(willMessage); // MQTT TLS support if (_brokerSettings.BrokerUseTls) { if (_brokerSettings.BrokerTlsSettings == null) { throw new ArgumentNullException(nameof(_brokerSettings.BrokerTlsSettings)); } var tlsOptions = new MqttClientOptionsBuilderTlsParameters { UseTls = _brokerSettings.BrokerUseTls, AllowUntrustedCertificates = _brokerSettings.BrokerTlsSettings.AllowUntrustedCertificates, IgnoreCertificateChainErrors = _brokerSettings.BrokerTlsSettings.IgnoreCertificateChainErrors, IgnoreCertificateRevocationErrors = _brokerSettings.BrokerTlsSettings.IgnoreCertificateRevocationErrors, SslProtocol = _brokerSettings.BrokerTlsSettings.SslProtocol, Certificates = _brokerSettings.BrokerTlsSettings.Certificates }; optionsBuilder.WithTls(tlsOptions); } // MQTT credentials if (!string.IsNullOrEmpty(_brokerSettings.BrokerUsername) && !string.IsNullOrEmpty(_brokerSettings.BrokerPassword)) { optionsBuilder.WithCredentials(_brokerSettings.BrokerUsername, _brokerSettings.BrokerPassword); } var managedOptions = new ManagedMqttClientOptionsBuilder() .WithAutoReconnectDelay(TimeSpan.FromSeconds(_brokerSettings.BrokerReconnectDelay)) .WithClientOptions(optionsBuilder.Build()) .Build(); // Subscribe to MQTT messages await SubscribeAsync(cancellationToken) .ConfigureAwait(false); // Connect to MQTT await MqttClient.StartAsync(managedOptions) .ConfigureAwait(false); // Call startup on inheriting service class await StartServiceAsync(cancellationToken) .ConfigureAwait(false); _serviceLog.LogInformation("Service started successfully"); }