dotnet / dotnet/MQTTnet

First connection attempt of ManagedClient is always failing

Open
#1,944 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
C#
Stars
5.1k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

### Describe the bug
The first connection my ManagedClient is starting is always failing. The server does not get any authentication request. The bug is only happening on the client side not on the server side. I've tried debugging it and the only event I'm getting into is the CertificateValidationHandler of the ManagedClient. The code inside CertificateValidationHandler is working fine and returning true at the end. Directly after that I'm already getting in the ConnectingFailedAsync event.
This bug is only happening on the very first connect attempt. After that everything is working fine.

### Which component is your bug related to?
- ManagedClient

### To Reproduce
Steps to reproduce the behavior:
1. Using this version of MQTTnet '4.3.3.952'.
2. Run the code below.
4. See error.

### Expected behavior
Should work on the first attempt

### Additional context / logging
Error log:
```batch
ConnectingFailedAsync: 'MQTTnet.Adapter.MqttConnectingFailedException: Error while authenticating. Connection closed.
---> MQTTnet.Exceptions.MqttCommunicationException: Connection closed.
at MQTTnet.Client.MqttClient.Authenticate(IMqttChannelAdapter channelAdapter, MqttClientOptions options, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at MQTTnet.Client.MqttClient.Authenticate(IMqttChannelAdapter channelAdapter, MqttClientOptions options, CancellationToken cancellationToken)
at MQTTnet.Client.MqttClient.ConnectInternal(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
at MQTTnet.Client.MqttClient.ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken)
at MQTTnet.Client.MqttClient.ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken)
at MQTTnet.Extensions.ManagedClient.ManagedMqttClient.ReconnectIfRequiredAsync(CancellationToken cancellationToken)'
```
### Code example
Please provide full code examples below where possible to make it easier for the developers to check your issues.

**Ideally a Unit Test (which shows the error) is provided so that the behavior can be reproduced easily.**

```csharp
public async Task ConfigureAsync(MqttClientSettings clientSettings, int msTimeout = 10000)
{
if (clientSettings == null)
throw new Exception("Mqtt client settings are null!");

_msTimeout = msTimeout <= 0 ? 10000 : msTimeout;

_certificateCollection.Clear();
_certificateCollection.Add(new X509Certificate2(clientSettings.ClientCertificate.Path, clientSettings.ClientCertificate.Password,
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet));

var mqttFactory = new MqttFactory();
var mqttClient = mqttFactory.CreateManagedMqttClient();

mqttClient.ApplicationMessageReceivedAsync += this.ApplicationMessageReceivedAsync;
mqttClient.ConnectedAsync += this.ConnectedAsync;
//mqttClient.ConnectingAsync += this.ConnectingAsync;
mqttClient.ConnectedAsync += this.ConnectedAsync;
mqttClient.DisconnectedAsync += this.DisconnectedAsync;
mqttClient.ConnectingFailedAsync += this.ConnectingFailedAsync;
mqttClient.ConnectionStateChangedAsync += this.ConnectionStateChangedAsync;
//mqttClient.InspectPacketAsync += this.InspectPacketAsync;

var mqttTlsOptions = new MqttClientTlsOptionsBuilder()
.UseTls(clientSettings.EnableTls)
.WithAllowUntrustedCertificates(true)
.WithSslProtocols(System.Security.Authentication.SslProtocols.Tls12)
.WithClientCertificatesProvider(this)
.WithCertificateValidationHandler(this.CertificateValidationHandler)
.Build();

var mqttClientOptionBuilder = new MqttClientOptionsBuilder()
.WithClientId(clientSettings.ClientId)
.WithCredentials(clientSettings.UserName, clientSettings.Password)
.WithTcpServer(clientSettings.Host, clientSettings.Port)
.WithTlsOptions(mqttTlsOptions)
.WithProtocolVersion(MqttProtocolVersion.V500)
.WithWillQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce)
.WithCleanStart(clientSettings.UseCleanSession)
.Build();

var mqttClientOptions = new ManagedMqttClientOptionsBuilder().WithClientOptions(mqttClientOptionBuilder).Build();

_mqttClient = mqttClient;
_clientOptions = mqttClientOptions;
await StartClientAsync();
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.