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

使用C#测试MQTTnet 4.1连接EMQX Broker时程序异常退出求助

MQTTnet客户端无法稳定连接EMQX Broker并异常退出问题

我在VS2019环境中使用C#开发,安装了NuGet包MQTTnet.4.1.4.563,参考相关示例代码尝试连接本地运行的EMQX Broker(桌面客户端为MQTTX),但无法建立稳定连接以实现主题的发布与订阅。我的Angular Web客户端可正常与该Broker收发消息,但编写的Program.cs代码中,程序执行到await Task.Delay(TimeSpan.FromSeconds(10));时异常退出,VS输出窗口显示最终信息为The program '[787944] mqtt-dotnet-sample1.exe' has exited with code 0 (0x0).

我的Program.cs代码

using System;
using System.Threading.Tasks;
using System.Threading;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet;
using System.Text.Json;

namespace mqtt_dotnet_sample1
{
    class Program
    {
        static void Main(string[] args)
        {
            Task task = ConnectAndSendMessage();
        }
        
        public static async Task ConnectAndSendMessage()
        {
            IManagedMqttClient _mqttClient = new MqttFactory().CreateManagedMqttClient();
            MqttClientOptionsBuilder builder = new MqttClientOptionsBuilder()
                                        .WithClientId("MY_CLIENT_ID")   // 与Angular 14的TypeScript客户端使用相同的连接标识
                                        .WithWebSocketServer("broker.emqx.io");

            ManagedMqttClientOptions options = new ManagedMqttClientOptionsBuilder()
                        .WithAutoReconnectDelay(TimeSpan.FromSeconds(60))
                        .WithClientOptions(builder.Build())
                        .Build();


            // 设置事件处理器
            _mqttClient.ConnectedAsync += _mqttClient_ConnectedAsync;
            _mqttClient.DisconnectedAsync += _mqttClient_DisconnectedAsync;
            _mqttClient.ConnectingFailedAsync += _mqttClient_ConnectingFailedAsync;

            // 连接到Broker
            Console.WriteLine("Attempting to connect to broker...");
            await _mqttClient.StartAsync(options);

            // 每秒向Broker发送一条新消息
            while (true)
            {
                string json = JsonSerializer.Serialize(new { message = "Hi from MqttNet", sent = DateTime.UtcNow });
                await _mqttClient.EnqueueAsync("bob-top", json);

                await Task.Delay(TimeSpan.FromSeconds(10));   // ** 程序在此处退出 **
            }
            Task _mqttClient_ConnectedAsync(MqttClientConnectedEventArgs arg)
            {
                Console.WriteLine("Connected");
                return Task.CompletedTask;
            };
            Task _mqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
            {
                Console.WriteLine("Disconnected");
                return Task.CompletedTask;
            };
            Task _mqttClient_ConnectingFailedAsync(ConnectingFailedEventArgs arg)
            {
                Console.WriteLine("Connection failed check network or broker!");
                return Task.CompletedTask;
            }
        }
    }
}

VS输出窗口信息

'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\mqtt-dotnet-sample1.exe'. Symbols loaded.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\MQTTnet.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\MQTTnet.Extensions.ManagedClient.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Text.Json.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\netstandard\v4.0_2.0.0.0__cc7b13ffcd2ddd51\netstandard.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\Microsoft.Bcl.AsyncInterfaces.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Memory.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.ValueTuple.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Text.Encodings.Web.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Runtime.CompilerServices.Unsafe.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Threading.Tasks.Extensions.dll'. 
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Buffers.dll'. 
The program '[787944] mqtt-dotnet-sample1.exe' has exited with code 0 (0x0).

问题修复建议

1. 主线程未等待异步任务完成

Main方法仅创建异步任务但未等待其执行,导致主线程直接退出,整个程序终止。修改Main方法为异步并等待任务:

static async Task Main(string[] args)
{
    await ConnectAndSendMessage();
}

如果是.NET Framework环境不支持异步Main,可改为:

static void Main(string[] args)
{
    ConnectAndSendMessage().GetAwaiter().GetResult();
}

2. 事件处理函数定义位置错误

三个事件处理函数定义在while(true)循环之后,永远不会被执行到,导致事件绑定的是未初始化的委托。需要将函数定义移至事件绑定之前:

public static async Task ConnectAndSendMessage()
{
    IManagedMqttClient _mqttClient = new MqttFactory().CreateManagedMqttClient();

    // 先定义事件处理函数
    Task _mqttClient_ConnectedAsync(MqttClientConnectedEventArgs arg)
    {
        Console.WriteLine("Connected");
        return Task.CompletedTask;
    };
    Task _mqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
    {
        Console.WriteLine("Disconnected");
        return Task.CompletedTask;
    };
    Task _mqttClient_ConnectingFailedAsync(ConnectingFailedEventArgs arg)
    {
        Console.WriteLine("Connection failed check network or broker!");
        return Task.CompletedTask;
    }

    // 再创建客户端选项并绑定事件
    MqttClientOptionsBuilder builder = new MqttClientOptionsBuilder()
                                .WithClientId("MY_CLIENT_ID")
                                .WithWebSocketServer("ws://localhost:8083"); // 改为本地EMQX的WebSocket地址

    ManagedMqttClientOptions options = new ManagedMqttClientOptionsBuilder()
                .WithAutoReconnectDelay(TimeSpan.FromSeconds(60))
                .WithClientOptions(builder.Build())
                .Build();

    _mqttClient.ConnectedAsync += _mqttClient_ConnectedAsync;
    _mqttClient.DisconnectedAsync += _mqttClient_DisconnectedAsync;
    _mqttClient.ConnectingFailedAsync += _mqttClient_ConnectingFailedAsync;

    // 后续连接与循环逻辑...
}

3. Broker地址不匹配

代码中使用的是公共Brokerbroker.emqx.io,但你实际要连接本地EMQX,需改为本地WebSocket地址(默认端口8083):ws://localhost:8083,如果用TCP连接则改为.WithTcpServer("localhost", 1883)。

4. ClientID重复问题

如果Angular客户端与C#客户端使用相同的MY_CLIENT_ID,Broker会强制踢掉之前的连接,导致不稳定。建议给C#客户端设置唯一的ClientID,例如:

.WithClientId($"C#_Client_{Guid.NewGuid()}")

内容的提问来源于stack exchange,提问作者bob.mazzo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:31:22