Mqttnet: Publish WithExactlyOnceQoS with 2 Clients and 1 Broker in the same application results in disconnects

Created on 4 Nov 2020  路  6Comments  路  Source: chkr1011/MQTTnet

Describe the bug

When publishing a message with QoS "WithExactlyOnceQoS" the Client gets disconnected immediately after the receipt of the message. QoS "WithAtMostOnceQoS" works as expected.

Which project is your bug related to?

  • ManagedClient
  • Server

To Reproduce

run program below, change QoS in Line 87

Expected behavior

Client should not disconnect after message receipt.

Screenshots

Expected

2020-11-04_09h25_30

Current

2020-11-04_09h26_38

using MQTTnet;
using MQTTnet.Client.Options;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Server;
using System;
using System.Text;
using System.Threading.Tasks;

namespace MQTTnet_Test1
{
    class Program
    {
        private IMqttServer LocalServer;

        static void Main(string[] args)
        {
            var p = new Program();

            p.StartServer();

            var client1 = p.StartClient("client1");
            var client2 = p.StartClient("client2");

            Task.Delay(1000);

            var message = new MqttApplicationMessageBuilder().WithTopic("topic1").WithPayload("Hello World").WithExactlyOnceQoS().WithRetainFlag().Build();

            client1.PublishAsync(message);

            Console.ReadLine();
        }

        private void StartServer()
        {
            var optionsBuilder = new MqttServerOptionsBuilder().WithConnectionBacklog(100).WithDefaultEndpointPort(1883);
            LocalServer = new MqttFactory().CreateMqttServer();
            LocalServer.StartAsync(optionsBuilder.Build());
            LocalServer.UseClientConnectedHandler(evt =>
            {
                Console.WriteLine(string.Format("SERVER - Client connected {0}", evt.ClientId));
            });
            LocalServer.UseClientDisconnectedHandler(evt =>
            {
                Console.WriteLine(string.Format("SERVER - Client disconnected {0}", evt.ClientId));
            });
            LocalServer.UseApplicationMessageReceivedHandler(msgEvt =>
            {
                Console.WriteLine(string.Format("SERVER - Message received from: {0}, topic: {1}, content: {2}", msgEvt.ClientId, msgEvt.ApplicationMessage.Topic, msgEvt.ApplicationMessage.ConvertPayloadToString()));
            });
        }

        private IManagedMqttClient StartClient(string clientid)
        {
            var options = new ManagedMqttClientOptionsBuilder()
               .WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
               .WithClientOptions(new MqttClientOptionsBuilder().WithClientId(clientid).WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500).WithTcpServer("localhost").Build())
               .Build();

            var client = new MqttFactory().CreateManagedMqttClient();

            client.UseApplicationMessageReceivedHandler(e =>
            {
                Console.WriteLine("### RECEIVED APPLICATION MESSAGE ###");
                Console.WriteLine($"+ Client = {clientid}");
                Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");
                Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
                Console.WriteLine($"+ QoS = {e.ApplicationMessage.QualityOfServiceLevel}");
                Console.WriteLine($"+ Retain = {e.ApplicationMessage.Retain}");
                Console.WriteLine();
            });

            client.UseConnectedHandler(e =>
            {
                Console.WriteLine("Client connected successfully {0}", e);
            });

            client.UseDisconnectedHandler(e =>
            {
                Console.WriteLine("Client disconnected {0}", e);
            });

            client.StartAsync(options);
            var topic = "topic1";



            // -------------------- PROBLEM ------------------------------------------
            // works
            //client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic(topic).WithAtMostOnceQoS().Build());
            // doesn't work
            client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic(topic).WithExactlyOnceQoS().Build());



            return client;
        }
    }
}

bug

Most helpful comment

The issue is located in the server implementation of MQTTv5.

All 6 comments

Hi, thanks for reporting this issue. It is a problem with MQTT v5 and will be fixed with the next version. I was able to reproduce it in a new Unit Test.

Hi @chkr1011, can you say if thats a bug in the Client or the Server. It would be good to know for me, because the I'm using the Server just for testing, but the Client will connet to another MQTT-Server in production. So I can descide if I have to wait for the fix.

cheers

The issue is located in the server implementation of MQTTv5.

Waiting for this fix too ;) using Mqtt v5. with QoS 2 from Pahoo Mqtt sending messages to the MqttServer ;)

Please test with latest RC.

@chkr1011 looks good for me, works as expected 馃憤

Was this page helpful?
0 / 5 - 0 ratings