By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Describe the bug

I have a Xamarin App using IMqttClient , the app captures a coordinate and then it sends it through mqtt to a Server.
In my code I use publishAsync like this await mqttClient.PublishAsync(message, CancellationToken.None); (the full code will be posted) and when I used await the code sends the message but it gets blocked on the await as if the process of publishing is not finished.

Which project is your bug related to?

  • Client
  • To Reproduce

    Steps to reproduce the behavior:

    Using this version of MQTTnet 'v3.0.11'.

    Run this code await mqttClient.PublishAsync(message, CancellationToken.None); .

    See error: Code does not continue even when it sends the message.

    Expected behavior

    After a sucessfull publish the code should be released from the await so the dev can do any other process.

    Screenshots

    This is the debug view

    It shows that gets the coordinate and then connect and sends the data.. On the right I'm subscribe to the same topic. After sending the message I have this log that it is not shown on the debug.

    Code example

    This is my MqttClient Class.

    using MQTTnet;
    using MQTTnet.Client;
    using MQTTnet.Client.Connecting;
    using MQTTnet.Client.Options;
    using MQTTnet.Client.Publishing;
    using MQTTnet.Internal;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Xamarin.Essentials;
    using XSales.Maps.Mobile.Global;
    using XSales.Maps.Mobile.Models;
    namespace XSales.Maps.Mobile.Mqtt 
        public class MQTTclient
            private IMqttClientOptions manageClientOptions;
            public IMqttClient mqttClient;
            private IMqttClientOptions clientOptions;
            // Create a new MQTT client.
            private MqttFactory factory;
            private static string clientId = "03cb09bf-0d04-4228-8b71-b87ed10e7492";
            bool mqttSecure = false;
            public Action<MqttClientConnectedEventArgs> mqttActionConnected;
            public Action<MqttApplicationMessageReceivedEventArgs> mqttMessageReceived;
            public MQTTclient(string url)
                factory = new MqttFactory();
                mqttClient = factory.CreateMqttClient();
                var site = url.Split(':');
                var uri = site[0];
                var port = Int32.Parse(site[1]);
                clientOptions = new MqttClientOptionsBuilder()
                    .WithClientId(clientId)
                    .WithCommunicationTimeout(new TimeSpan(0,30,0))
                    .WithTcpServer(uri, port)
                    .WithCleanSession()
                    .Build();
            public void ConnectClientAsync()
                if (!mqttClient.IsConnected)
                    mqttClient.UseDisconnectedHandler(e =>
                        Util.Log(Util.LogType.Debug, MethodBase.GetCurrentMethod(), JsonConvert.SerializeObject(e));
                        Util.Log(Util.LogType.Debug, MethodBase.GetCurrentMethod(), "### DISCONNECTED FROM SERVER ###");
                    });
                    mqttClient.UseConnectedHandler(async e =>
                        Util.Log(Util.LogType.Information, MethodBase.GetCurrentMethod(), "### CONNECTED WITH SERVER ###");
                        // Subscribe to a topic
                        await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic("topic/tracking").Build());
                        Util.Log(Util.LogType.Debug, MethodBase.GetCurrentMethod(), "### SUBSCRIBED ###");
    
    
    
    
        
    
                    });
                    //mqttClient.UseApplicationMessageReceivedHandler(e =>
                    //    Console.WriteLine("### RECEIVED APPLICATION MESSAGE ###");
                    //    Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");
                    //    Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
                    //    Console.WriteLine();
                    //});
                    mqttClient.UseApplicationMessageReceivedHandler(mqttMessageReceived);
                    mqttClient.ConnectAsync(clientOptions, CancellationToken.None).Wait();
            public async Task ClientDisconnect()
                await mqttClient.DisconnectAsync();
            public async Task PublishAsync(string topic, string payload, bool retainFlag = true, int qos = 2)
                if (mqttClient.IsConnected)
                        var message = new MqttApplicationMessageBuilder()
                                    .WithTopic(topic)
                                    .WithPayload(payload)
                                    .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce)
                                    .WithRetainFlag(retainFlag)
                                    .Build();
                        Util.Log(Util.LogType.Debug, MethodBase.GetCurrentMethod(),$"### SENDING MESSAGE TO SERVER ### {payload}");
                        await mqttClient.PublishAsync(message, CancellationToken.None);
                        return;
                    catch (TaskCanceledException tce)
                        Util.Log(Util.LogType.Debug, MethodBase.GetCurrentMethod(), $"Task Cancelled: {tce.Message}");
                        return;
                    catch (Exception ex)
                        Util.Log(Util.LogType.Debug, MethodBase.GetCurrentMethod(), $"No: {ex.Message} | {ex.Source}");
                        return;
    

    And this is the method I use to send the data.

            public async Task SendDataMqtt(MqttDataType mqttDataType, object oPayload)
                var m = MethodBase.GetCurrentMethod();
                var dataTask = App.Database.GetDataAsync();
                var data = dataTask.Result;
                switch (mqttDataType)
                    case MqttDataType.Tracking:
                        var coordinate = (Coord)oPayload;
                        if (coordinate != null)
                            Log(LogType.Debug, m, $"Creating header object to send");
                            Log(LogType.Debug, m, $"Creating MQTT Client");
                            var mqtt = new MQTTclient(data.hostname);
                            mqtt.mqttMessageReceived = e =>
                                Console.WriteLine("### RECEIVED APPLICATION MESSAGE ###");
                                Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");
                                Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
                                Console.WriteLine();
                            mqtt.ConnectClientAsync();
                            var header = new List<Header>();
                            header.Add(new Header
                                order = 1,
                                key = "reference",
                                label = "",
                                value = $"{data.ownCode}-{data.ownName} {DateTime.Now}"
                            });
                            Log(LogType.Debug, m, $"Creating MQTT Payload");
                            var payload = new MqttPayload()
                                user = data.email,
                                latitude = coordinate.latitude,
                                longitude = coordinate.longitude,
                                date = coordinate.date.ToString("yyyy-MM-dd HH:mm:ss"),
                                token = data.token,
                                header = header
                            Log(LogType.Debug, m, $"Trying to publish PAYLOAD coordinates in MQTT");
                            await mqtt.PublishAsync("topic/tracking", JsonConvert.SerializeObject(payload));
                            Log(LogType.Debug, m, $"Coordinate Published");
                            //coord.sent = true;
                            //App.Database.UpdateCoordAsync(coord);
                            await mqtt.ClientDisconnect();
                        break;
              

    Please try with QoS 0 and 1 (just for testing). Also please change "Wait" and "Result" calls to proper "await" ones.

    Apart from that the code looks OK to me. I assume it is a problem with async/await and Xamarin. So nothing which is located in this lib directly. I also have a Xamarin project which uses this lib and it works without problems (latest version of MQTTnet).