You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor MAUI中使用MQTTnet无法读取订阅主题的消息

问题解决:MQTTnet v4 消息接收事件未触发及负载读取方案

核心问题分析

你的代码中最关键的错误是使用using语句包裹mqttClient:当SubscribeTopic方法执行完毕后,using块会立即释放MQTT客户端实例,导致客户端在订阅成功后被销毁,根本无法接收后续消息。此外,还需要正确处理消息负载的解析。

修正后的代码实现

using System.Diagnostics;
using System.Text;
using MQTTnet;
using MQTTnet.Client;

namespace Beacons.Data;

public static class MQTT_Client_Subscribe
{
    // 保留客户端实例,避免被立即释放
    private static IMqttClient? _mqttClient;

    public static async Task SubscribeTopic()
    {
        var mqttFactory = new MqttFactory();
        _mqttClient = mqttFactory.CreateMqttClient();

        var mqttClientOptions = new MqttClientOptionsBuilder()
            .WithClientId(Guid.NewGuid().ToString())
            .WithTcpServer("mqtt.ip.address", 1883)
            .WithCredentials("user", "password")
            // 可选:配置重连逻辑,提升稳定性
            .WithAutomaticReconnect()
            .Build();

        // 订阅消息接收事件
        _mqttClient.ApplicationMessageReceivedAsync += async e =>
        {
            // 将字节数组负载转换为JSON字符串
            var payload = Encoding.UTF8.GetString(e.ApplicationMessage.PayloadSegment);
            
            Debug.WriteLine("收到MQTT消息:");
            Debug.WriteLine(payload);
            Console.WriteLine(payload); // 同时输出到控制台,便于Blazor MAUI调试查看
            
            await Task.CompletedTask;
        };

        // 连接到Broker
        await _mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
        Debug.WriteLine("MQTT客户端已连接");

        // 订阅主题(可指定QoS,默认0)
        var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
            .WithTopicFilter(f =>
            {
                f.WithTopic("beacon/publish")
                 .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
            })
            .Build();

        var response = await _mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
        Debug.WriteLine("MQTT客户端已订阅主题");
        
        // 验证订阅结果
        foreach (var result in response.Items)
        {
            Debug.WriteLine($"主题 {result.TopicFilter.Topic} 订阅状态:{result.ResultCode}");
        }
    }

    // 可选:提供手动断开方法
    public static async Task Disconnect()
    {
        if (_mqttClient != null && _mqttClient.IsConnected)
        {
            await _mqttClient.DisconnectAsync();
            _mqttClient.Dispose();
            _mqttClient = null;
        }
    }
}

关键改动说明

  1. 移除using语句:将mqttClient改为静态字段_mqttClient,确保客户端实例在应用生命周期内保持存活,不会被提前释放。
  2. 负载解析:使用Encoding.UTF8.GetString(e.ApplicationMessage.PayloadSegment)将MQTT消息的字节数组负载转换为可读的JSON字符串。
  3. 添加重连逻辑:通过.WithAutomaticReconnect()配置自动重连,提升客户端稳定性。
  4. 订阅结果验证:遍历订阅响应结果,确认主题订阅成功。

Blazor MAUI页面调用注意事项

在Razor页面中调用时,确保正确处理异步逻辑,避免阻塞UI:

protected override async Task OnInitializedAsync()
{
    await MQTT_Client_Subscribe.SubscribeTopic();
    await base.OnInitializedAsync();
}

// 可选:页面销毁时断开连接
public async ValueTask DisposeAsync()
{
    await MQTT_Client_Subscribe.Disconnect();
}

调试建议

  • 确认主题名称完全匹配(区分大小写),确保和MQTTX中使用的订阅主题一致。
  • 检查Broker的连接日志,确认客户端是否成功订阅并接收消息。
  • 在Blazor MAUI中,优先查看输出窗口(而非控制台)获取Debug.WriteLine的输出内容。

内容的提问来源于stack exchange,提问作者Jaden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:18:13