【问题标题】:MQTT not connect to brokerMQTT 未连接到代理
【发布时间】:2021-10-21 02:38:49
【问题描述】:

我有一个 ASP.NET MVC 项目,其中一页必须显示我的设备状态。我想从代理 (broker.mqttdashboard.com) 获取使用 MQTT 的设备状态。我正在使用 MQTTnet。我无法连接到代理,我没有用户名或密码,我想使用公共频道通过按下按钮向代理发布消息。按钮运行PublishMqttMsg 方法,我想从代理发送消息。

我不知道如何连接到代理。谁能帮帮我?

我的控制器代码是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Protocol;
using System;
using System.Text;
using System.Threading.Tasks;
using MQTTnet.Diagnostics;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet;
using Microsoft.AspNet.Identity;

namespace WebApplication10.Controllers
{
    public class MqttController : Controller
    {
        private static IManagedMqttClient client;

        // GET: Mqtt
        public ActionResult Index()
        {
            var CurrentUser = User.Identity.GetUserId();
            ConnectAsync(CurrentUser, "broker.mqttdashboard.com", "", 8000, true);

           
            client.UseConnectedHandler(e =>
            {
                Console.WriteLine("Connected successfully with MQTT Brokers.");
            });

            client.UseDisconnectedHandler(e =>
            {
                Console.WriteLine("Disconnected from MQTT Brokers.");
            });

            client.UseApplicationMessageReceivedHandler(e =>
            {
                try
                {
                    string topic = e.ApplicationMessage.Topic;

                    if (string.IsNullOrWhiteSpace(topic) == false)
                    {
                        string payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                        Console.WriteLine($"Topic: {topic}. Message Received: {payload}");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message, ex);
                }
            });



            return View();
        }


        public ActionResult SubscribeMqttMsg()
        {
            SubscribeAsync("test_topic/1");
            return View("Index");
        }


        public ActionResult PublishMqttMsg()
        {
            PublishAsync("test_topic/1", "test message");
            return View("Index");
        }




            /// <summary>
            /// Connect to broker.
            /// </summary>
            /// <returns>Task.</returns>
            public static async Task ConnectAsync(string user, string uri, string pass, int port, bool userSSL)
        {
            string clientId = Guid.NewGuid().ToString();
            string mqttURI = uri;
            string mqttUser = user;
            string mqttPassword = pass;
            int mqttPort = port;
            bool mqttSecure = userSSL;

            var messageBuilder = new MqttClientOptionsBuilder()
              //.WithClientId(clientId)
              //.WithCredentials(mqttUser, mqttPassword)
              .WithTcpServer(mqttURI, mqttPort)
             .WithCleanSession();
             

            var options = mqttSecure
              ? messageBuilder
                .WithTls()
                .Build()
              : messageBuilder
                .Build();

            var managedOptions = new ManagedMqttClientOptionsBuilder()
              .WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
              .WithClientOptions(options)
              .Build();

            client = new MqttFactory().CreateManagedMqttClient();

            await client.StartAsync(managedOptions);
        }
        /// <summary>
        /// Publish Message.
        /// </summary>
        /// <param name="topic">Topic.</param>
        /// <param name="payload">Payload.</param>
        /// <param name="retainFlag">Retain flag.</param>
        /// <param name="qos">Quality of Service.</param>
        /// <returns>Task.</returns>
        public static async Task PublishAsync(string topic, string payload, bool retainFlag = true, int qos = 1) =>
          await client.PublishAsync(new MqttApplicationMessageBuilder()
            .WithTopic(topic)
            .WithPayload(payload)
            .WithQualityOfServiceLevel((MQTTnet.Protocol.MqttQualityOfServiceLevel)qos)
            .WithRetainFlag(retainFlag)
            .Build())
            ;


        /// <summary>
        /// Subscribe topic.
        /// </summary>
        /// <param name="topic">Topic.</param>
        /// <param name="qos">Quality of Service.</param>
        /// <returns>Task.</returns>
        public static async Task SubscribeAsync(string topic, int qos = 1) =>
          await client.SubscribeAsync(new TopicFilterBuilder()
            .WithTopic(topic)
            .WithQualityOfServiceLevel((MQTTnet.Protocol.MqttQualityOfServiceLevel)qos)
            .Build());


    }
}

【问题讨论】:

    标签: c# asp.net-mvc mqtt


    【解决方案1】:

    broker.hivemq.com 处的端口 8000 是“Websocket 端口”(因此通过 websockets 连接侦听 MQTT)。您正在尝试使用 TCP 客户端进行连接。更改端口(更改为 1833)或更改:

    var messageBuilder = new MqttClientOptionsBuilder()
       .WithTcpServer(mqttURI, mqttPort)
       ...
    

    到:

    var messageBuilder = new MqttClientOptionsBuilder()
       .WithWebSocketServer("broker.hivemq.com:8000/mqtt")
       ...
    

    (见the documentation)。

    【讨论】: