Xamarin.Forms MQTT单击按钮发布

时间:2018-09-19 17:23:56

标签: c# xamarin xamarin.forms mqtt xamarin-studio

我一直在研究Xamarin Forms(Visual Studio-我的第一个项目)中的一小段代码,以便在按下按钮时发送mqtt消息。 我已经编写了将mqtt消息发布到C#控制台应用程序中的test.mosquitto.org服务器的代码,并且效果很好

using System;
using System.Net.Mqtt;
using System.Text;

namespace MqttTest.Client
{
class Program
{
const string topic = "test/test/button";

    static void Main (string[] args)
    {
        var config = new MqttConfiguration { Port = 1883 };
        var client = MqttClient.CreateAsync("test.mosquitto.org", config).Result;
        var clientId = "myClientID";
        string message = "test";


        client.ConnectAsync (new MqttClientCredentials (clientId)).Wait ();
        client.SubscribeAsync (topic, MqttQualityOfService.AtLeastOnce).Wait ();
        //Publishes "message" Var 
        client.PublishAsync(new MqttApplicationMessage(topic, Encoding.UTF8.GetBytes($"{message}")), MqttQualityOfService.AtLeastOnce).Wait();
    }
}

}

现在,我已经编写了一个非常简单的xamarin跨平台应用程序,其中包含1个按钮,1个button_clicked事件以及在上述控制台应用程序中编写的按钮clicked事件的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.Net.Mqtt;

namespace App1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
const string topic = "test/test/button";

    private void Button_Clicked(object sender, EventArgs e)
    {
        var config = new MqttConfiguration { Port = 1883 };
        var client = MqttClient.CreateAsync("test.mosquitto.org", config).Result;
        var clientId = "clientIdhGHvpYY9uM";
        string message = "Hello";


        client.ConnectAsync(new MqttClientCredentials(clientId)).Wait();
        client.SubscribeAsync(topic, MqttQualityOfService.AtLeastOnce).Wait();
        client.PublishAsync(new MqttApplicationMessage(topic, Encoding.UTF8.GetBytes($"{message}")), MqttQualityOfService.AtLeastOnce).Wait();
    }
}

}

在模拟器中测试该应用程序后,它会加载好,但是当我单击该按钮时,它会冻结该应用程序(无法重新单击该按钮),并且不会发布到测试mqtt服务器。

任何人都可以提供有关如何使其正常工作的建议

谢谢

1 个答案:

答案 0 :(得分:1)

我有同样的问题。正如SushiHangover所指出的,按钮冻结的原因仅仅是您在主线程上进行连接。异步连接方法可能如下所示:

public async Task<bool> ConnectAsync()
{
    return await Task.Run(() =>
    {
        Log($"Connecting to {MqttSettings.Host}:{MqttSettings.Port}");

        try
        {
            var configuration = new MqttConfiguration();
            configuration.Port = SolaceSettings.Port;
            _mqttClient = MqttClient.CreateAsync(MqttSettings.Host, configuration).Result;
            _sessionState = _mqttClient.ConnectAsync(new MqttClientCredentials(MqttSettings.MqttClientId, MqttSettings.Username, MqttSettings.Password)).Result;

            Log("Connected.");
            return true;
        }
        catch (Exception ex)
        {
            Log($"Could not connect. {ex}");
            return false;
        }
    });
}

但是,这不能解决无法连接的根本原因。对我来说,有两个主要问题:

  • 不要在模拟器中运行,请使用真实的设备(至少在Mac位于代理服务器/防火墙之后的情况下)。
  • 我指定了一个随机客户端ID。在代理上配置了客户端ID并在客户端中使用了该ID后,它就可以工作。更新:显然,这是错误的,不需要使用。使用新的ID连接时,会自动生成客户端ID条目。