using System.Security.Authentication; using MqttConsoleAppClient; using MQTTnet; using MQTTnet.Client; using MQTTnet.Formatter; namespace MQTTnet.Samples.Client; public static class Client_Connection_Samples { public static async Task Connect_Client() { /* * This sample creates a simple MQTT client and connects to a public broker. * * Always dispose the client when it is no longer used. * The default version of MQTT is 3.1.1. */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { // Use builder classes where possible in this project. var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1").Build(); // This will throw an exception if the server is not available. // The result from this message returns additional data which was sent // from the server. Please refer to the MQTT protocol specification for details. var response = await mqttClient.ConnectAsync(mqttClientOptions); mqttClient.PublishAsync(new MqttApplicationMessage() { }); mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync; Console.WriteLine("The MQTT client is connected."); response.DumpToConsole(); Console.ReadLine(); // Send a clean disconnect to the server by calling _DisconnectAsync_. Without this the TCP connection // gets dropped and the server will handle this as a non clean disconnect (see MQTT spec for details). //var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder().Build(); //await mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None); } } private static Task MqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg) { throw new NotImplementedException(); } public static async Task Connect_Client_Timeout() { /* * This sample creates a simple MQTT client and connects to an invalid broker using a timeout. * * This is a modified version of the sample _Connect_Client_! See other sample for more details. */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1").Build(); try { using (var timeoutToken = new CancellationTokenSource(TimeSpan.FromHours(1))) { await mqttClient.ConnectAsync(mqttClientOptions, timeoutToken.Token); } } catch (OperationCanceledException) { Console.WriteLine("Timeout while connecting."); } } } public static async Task Connect_Client_Using_MQTTv5() { /* * This sample creates a simple MQTT client and connects to a public broker using MQTTv5. * * This is a modified version of the sample _Connect_Client_! See other sample for more details. */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").WithProtocolVersion(MqttProtocolVersion.V500).Build(); // In MQTTv5 the response contains much more information. var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None); Console.WriteLine("The MQTT client is connected."); response.DumpToConsole(); } } public static async Task Connect_Client_Using_TLS_1_2() { /* * This sample creates a simple MQTT client and connects to a public broker using TLS 1.2 encryption. * * This is a modified version of the sample _Connect_Client_! See other sample for more details. */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("mqtt.fluux.io") .WithTls( o => { // The used public broker sometimes has invalid certificates. This sample accepts all // certificates. This should not be used in live environments. o.CertificateValidationHandler = _ => true; // The default value is determined by the OS. Set manually to force version. o.SslProtocol = SslProtocols.Tls12; }) .Build(); using (var timeout = new CancellationTokenSource(5000)) { await mqttClient.ConnectAsync(mqttClientOptions, timeout.Token); Console.WriteLine("The MQTT client is connected."); } } } public static async Task Connect_Client_Using_WebSockets() { /* * This sample creates a simple MQTT client and connects to a public broker using a WebSocket connection. * * This is a modified version of the sample _Connect_Client_! See other sample for more details. */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { var mqttClientOptions = new MqttClientOptionsBuilder().WithWebSocketServer("broker.hivemq.com:8000/mqtt").Build(); var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None); Console.WriteLine("The MQTT client is connected."); response.DumpToConsole(); } } public static async Task Connect_Client_With_TLS_Encryption() { /* * This sample creates a simple MQTT client and connects to a public broker with enabled TLS encryption. * * This is a modified version of the sample _Connect_Client_! See other sample for more details. */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 8883) .WithTls( o => { // The used public broker sometimes has invalid certificates. This sample accepts all // certificates. This should not be used in live environments. o.CertificateValidationHandler = _ => true; }) .Build(); // In MQTTv5 the response contains much more information. using (var timeout = new CancellationTokenSource(5000)) { var response = await mqttClient.ConnectAsync(mqttClientOptions, timeout.Token); Console.WriteLine("The MQTT client is connected."); response.DumpToConsole(); } } } public static async Task Inspect_Certificate_Validation_Errors() { /* * This sample prints the certificate information while connection. This data can be used to decide whether a connection is secure or not * including the reason for that status. */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("mqtt.fluux.io", 8883) .WithTls( o => { o.CertificateValidationHandler = eventArgs => { eventArgs.Certificate.Subject.DumpToConsole(); eventArgs.Certificate.GetExpirationDateString().DumpToConsole(); eventArgs.Chain.ChainPolicy.RevocationMode.DumpToConsole(); eventArgs.Chain.ChainStatus.DumpToConsole(); eventArgs.SslPolicyErrors.DumpToConsole(); return true; }; }) .Build(); // In MQTTv5 the response contains much more information. using (var timeout = new CancellationTokenSource(5000)) { await mqttClient.ConnectAsync(mqttClientOptions, timeout.Token); } } } public static async Task Ping_Server() { /* * This sample sends a PINGREQ packet to the server and waits for a reply. * * This is only supported in METTv5.0.0+. */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build(); await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None); // This will throw an exception if the server does not reply. await mqttClient.PingAsync(CancellationToken.None); Console.WriteLine("The MQTT server replied to the ping request."); } } public static async Task Reconnect_Using_Event() { /* * This sample shows how to reconnect when the connection was dropped. * This approach uses one of the events from the client. * This approach has a risk of dead locks! Consider using the timer approach (see sample). */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build(); mqttClient.DisconnectedAsync += async e => { if (e.ClientWasConnected) { // Use the current options as the new options. await mqttClient.ConnectAsync(mqttClient.Options); } }; await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None); } } public static void Reconnect_Using_Timer() { /* * This sample shows how to reconnect when the connection was dropped. * This approach uses a custom Task/Thread which will monitor the connection status. * This is the recommended way but requires more custom code! */ var mqttFactory = new MqttFactory(); using (var mqttClient = mqttFactory.CreateMqttClient()) { var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build(); _ = Task.Run( async () => { // User proper cancellation and no while(true). while (true) { try { // This code will also do the very first connect! So no call to _ConnectAsync_ is required // in the first place. if (!mqttClient.IsConnected) { await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None); // Subscribe to topics when session is clean etc. Console.WriteLine("The MQTT client is connected."); } } catch { // Handle the exception properly (logging etc.). } finally { // Check the connection state every 5 seconds and perform a reconnect if required. await Task.Delay(TimeSpan.FromSeconds(5)); } } }); } } }