320 lines
12 KiB
C#
320 lines
12 KiB
C#
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));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
} |