MQTTnet icon indicating copy to clipboard operation
MQTTnet copied to clipboard

Bug? Client Subscription to messages not working?

Open BennyBread opened this issue 5 years ago • 6 comments

Describe the bug

A clear and concise description of what the bug is. I wrote a stackoverflow message some days ago which describes the problem: https://stackoverflow.com/questions/59818055/mqttnet-client-not-getting-subscribed-topics

Which project is your bug related to?

  • Client

To Reproduce

Steps to reproduce the behavior:

  1. Using the latest version of MQTTnet from nuget
  2. Run this code '....'.

To not repeat everyting from the stackoverflow post here in short:

MqttClient client = new MqttFactory().CreateMqttClient(); client.UseApplicationMessageReceivedHandler( e => { HandleMessageReceived(e.ApplicationMessage); });

pseudo code: client.connect(). After (successful) connect call client.Subscribe() to topic e.g. "Home/Heater/control/*"

ERROR: The function "HandleMessageReceived" is never called when I publish a message to the broker e.g. "Home/Heater/control/test"

Expected behavior

I expect that the message handler which was installed through Client.UseApplicationMessageReceivedHandler is called if I publish a message to the subscribed topic.

I don't know if it is really a bug or if I am doing something wrong. If needed I can post full code to reproduce. (I will need to extract the relevant things from my project to a small sample project)

Hopefully someone can help...

BennyBread avatar Jan 21 '20 15:01 BennyBread

Can confirm, something's wrong with the managed client.

var clientOptions = new ManagedMqttClientOptionsBuilder()
                .WithAutoReconnectDelay(TimeSpan.FromSeconds(1))
                .WithClientOptions(new MqttClientOptionsBuilder()
                    .WithClientId("testclient")
                    .WithCredentials("abc", "1234567890")
                    .WithTcpServer("192.168.1.1", 1883)
                    .Build())
                .Build();

            var mqttClient = new MqttFactory().CreateManagedMqttClient();
            mqttClient.ConnectedHandler = new ConnectedHandler();
            mqttClient.DisconnectedHandler = new DisconnectedHandler();
            mqttClient.ConnectingFailedHandler = new ConnectionFailedHandler();
            mqttClient.ApplicationMessageProcessedHandler = new MessageReceivedHandler();
            mqttClient.ApplicationMessageSkippedHandler = new MessageSkippedHandler();

            await mqttClient.StartAsync(clientOptions);
            await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic("receiver/+/message").Build());

IMqttClientConnectedHandler and IMqttClientDisconnectedHandler instances are being called, IApplicationMessageProcessedHandler is ignored.

I tried connecting to Mosquitto and a MqttNet Broker with the ManagedClient 3.08 and 3.09-rc1, same issue on both versions. A nodejs MQTT client reads the messages just fine.

//edit: When using

mqttClient.UseConnectedHandler(async e =>
            {
                Console.WriteLine($"{DateTime.Now.ToShortTimeString()} connected.");
                await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic("receiver/+/message").Build());
            });
            mqttClient.UseDisconnectedHandler(async e =>
            {
                Console.WriteLine($"{DateTime.Now.ToShortTimeString()} disconnected");
            });
            mqttClient.UseApplicationMessageReceivedHandler(async e =>
            {
                Console.WriteLine($"{DateTime.Now.ToShortTimeString()} received: {e.ApplicationMessage.ConvertPayloadToString()}");
            });

the MessageReceived handler is called and the message available. What is the difference between both approaches? And why's the Connected handler called in the first sample but not the the MessageReceived handler?

mplogas avatar Feb 17 '20 18:02 mplogas

SubscribeAsync takes as parameter IEnumerable<TopicFilter>. So I have done the following:

var TopicFilterList = new List<TopicFilter>(); TopicFilterList.Add(new TopicFilterBuilder().WithTopic(topic1).WithAtMostOnceQoS().Build()); TopicFilterList.Add(new TopicFilterBuilder().WithTopic(topic2).WithAtLeastOnceQoS().Build()); await client.SubscribeAsync(TopicFilterList);

This works well for me.

JManGr avatar Mar 01 '20 07:03 JManGr

Hello, that was just proof of concept. So I did not like to put the code into Git. But I can show you the most important methods of my client. I hope that help you.

Best Regards Josef

Von: jrfaguilarmailto:[email protected] Gesendet: Montag, 30. März 2020 10:13 An: chkr1011/MQTTnetmailto:[email protected] Cc: JManGrmailto:[email protected]; Mentionmailto:[email protected] Betreff: Re: [chkr1011/MQTTnet] Bug? Client Subscription to messages not working? (#849)

SubscribeAsync takes as parameter IEnumerable. So I have done the following:

var TopicFilterList = new List<TopicFilter>(); TopicFilterList.Add(new TopicFilterBuilder().WithTopic(topic1).WithAtMostOnceQoS().Build()); TopicFilterList.Add(new TopicFilterBuilder().WithTopic(topic2).WithAtLeastOnceQoS().Build()); await client.SubscribeAsync(TopicFilterList);

This works well for me.

For me, its working well with only subscribing to one topic but when I subscribe to another topic, it doesn't receive the messages from none of them. (This applies to ManagedClient, with regular Client it's working ok) @JManGrhttps://github.com/JManGr could you post or send me your complete code to check it out? Thanks in advance.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/chkr1011/MQTTnet/issues/849#issuecomment-605850380, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGIGZPLGM744GXNCSWXLYHDRKBIDDANCNFSM4KJVACWQ.

public class JManMqttClient
{
    public string ClientId { get; private set; }
	private readonly string topicChatMsg;
    private readonly string topicNewMember;

    private IManagedMqttClient client = null;
	public JManMqttClient()
    {

        ClientId = Preferences.Get("ClientId", String.Empty);
        if (string.IsNullOrEmpty(ClientId))
        {
            ClientId = Guid.NewGuid().ToString();
        }

        topicChatMsg = $"JMan/Mttq/chat/GAll/{ClientId}/ChatMsg";
        topicNewMember = "JMan/Mttq/chat/GAll/NewMember";
        InitMttqClient();
    }

   
    public async void InitMttqClient()
    {
        var tlsOptions = new MqttClientTlsOptions
        {
            UseTls = true,
            IgnoreCertificateChainErrors = true,
            IgnoreCertificateRevocationErrors = true,
            AllowUntrustedCertificates = false
        };
        var options = new MqttClientOptions
        {
            ClientId = this.ClientId,
            ProtocolVersion = MqttProtocolVersion.V311,
            ChannelOptions = new MqttClientTcpOptions { Server = "?????", Port = 8883, TlsOptions = tlsOptions },
            Credentials = new MqttClientCredentials { Username = "?????", Password = Encoding.UTF8.GetBytes("???????") },
            CleanSession = true,
            
            KeepAlivePeriod = TimeSpan.FromSeconds(5)
        };

        var mqttFactory = new MqttFactory();
   
        client = mqttFactory.CreateManagedMqttClient();
       
        client.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(MttqReceiveHandler);
        client.UseConnectedHandler(OnConnected);
        client.DisconnectedHandler= new MqttClientDisconnectedHandlerDelegate(OnDisconnected);
        client.ConnectingFailedHandler=new ConnectingFailedHandlerDelegate(OnConnectingFailed);

        await client.StartAsync(new ManagedMqttClientOptions { ClientOptions = options });
    }

    private void OnConnectingFailed(ManagedProcessFailedEventArgs obj)
    {
        App.Current.MainPage.DisplayAlert("Error", obj.Exception.Message, "Ok");
    }

    private void MttqReceiveHandler(MqttApplicationMessageReceivedEventArgs obj)
    {
        if (obj.ApplicationMessage.Topic == topicChatMsg)
        {
            // do Topic ChatMsg
            return;
        }

        if (obj.ApplicationMessage.Topic == topicNewMember)
        {
            // Do Topic NewMember
            return;
        }
    }

    private async void OnConnected(MqttClientConnectedEventArgs obj)
    {
        var l = new List<TopicFilter>(); 
        l.Add(new TopicFilterBuilder().WithTopic(topicChatMsg).WithAtMostOnceQoS().Build());
        l.Add(new TopicFilterBuilder().WithTopic(topicNewMember).WithAtLeastOnceQoS().Build());
        await client.SubscribeAsync(l);
    }

    private async void OnDisconnected(MqttClientDisconnectedEventArgs obj)
    {

    }
}

JManGr avatar Mar 30 '20 14:03 JManGr

I am experiencing the same issue. I receive messages until, at some point, the messages are not received any more, although the MQTT server (Mosquitto in my case) is receiving and publishing them according to its logs.

If I use another MQTT client and it subscribes to the same topics, the client gets the messages but my mqttnet program doesn't.

manuelconesa avatar Oct 28 '21 19:10 manuelconesa

Please retest with the latest version 4. It got several improvements in the affected area so that I assume it is fixed. If not, please reopen this ticket.

chkr1011 avatar Sep 15 '22 06:09 chkr1011