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

MQTT客户端连接CrystalMQ鉴权报错:Unexpected Maximum QoS value:2 求解决方案

问题描述

使用以下MQTTnet配置连接CrystalMQ Broker:

_options = new MqttClientOptionsBuilder()
                    .WithClientId(ClientID)
                    .WithTcpServer(Globals.BROKER_ADDRESS, Globals.BROKER_PORT)
                    .WithCredentials(Globals.BROKER_USER, Globals.BROKER_PASSWORD) 
                    .WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500) // 使用MQTT 5.0版本
                    .WithTlsOptions(o =>
                    {
                        o.UseTls(true);
                        o.WithAllowUntrustedCertificates(false);
                        o.WithIgnoreCertificateChainErrors(false);
                        o.WithIgnoreCertificateRevocationErrors(false);

                        o.WithCertificateValidationHandler(_ => true);

                        Assembly assembly = Assembly.GetExecutingAssembly();

                        byte[]? certPubicKeyData = null;
                        using (MemoryStream mem = new())
                        {
                            assembly.GetManifestResourceStream("MqttClient.Certs.client.key")?.CopyTo(mem);

                            certPubicKeyData = mem.ToArray();
                        }

                        byte[]? certClientData = null;
                        using (MemoryStream mem = new())
                        {
                            assembly.GetManifestResourceStream("MqttClient.Certs.client.crt")?.CopyTo(mem);

                            certClientData = mem.ToArray();
                        }

                        byte[]? certRootData = null;
                        using (MemoryStream mem = new())
                        {
                            assembly.GetManifestResourceStream("MqttClient.Certs.root.crt")?.CopyTo(mem);

                            certRootData = mem.ToArray();
                        }

                        var rootCert = new X509Certificate2(certRootData);
                        var clientCert = new X509Certificate2(certClientData);
                        //var clientKey= new X509Certificate2(certPubicKeyData);
                        o.WithClientCertificates([rootCert, clientCert]);
                        o.WithSslProtocols(System.Security.Authentication.SslProtocols.Tls12);
                    })
                    .WithKeepAlivePeriod(TimeSpan.FromSeconds(60))
                    .WithWillQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce)
                    .WithCleanStart(true)
                    .WithSessionExpiryInterval(Globals.BROKER_SESSION_INTERVAL)
                    .Build();

连接触发Disconnected处理器,抛出异常:

Error while authenticating. Unexpected Maximum QoS value: 2

已尝试将遗嘱QoS改为MqttQualityOfServiceLevel.AtLeastOnce,问题依旧。询问是否存在无需修改MQTTnet源码的解决办法。

解决办法

以下是几个无需修改MQTTnet源码的可行方案:

  • 降级MQTT协议版本:将协议版本从MQTT 5.0改为3.1.1,部分Broker对MQTT 5.0的QoS协商支持不完善,降级后可规避该问题。修改配置中的协议版本行:

    .WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V311)
    
  • 强制设置客户端最大QoS等级:在配置中添加.WithMaximumQoS()方法,限制客户端使用的最大QoS为Broker支持的等级(比如AtLeastOnce或AtMostOnce),避免协商时出现Broker不支持的QoS值:

    .WithMaximumQoS(MqttQualityOfServiceLevel.AtLeastOnce)
    
  • 检查Broker配置:确认CrystalMQ Broker是否开启了QoS 2的支持,或者是否存在全局的最大QoS限制。如果Broker本身不支持QoS 2,即使客户端设置更低的QoS,握手时的协商逻辑仍可能触发该错误,需在Broker端调整配置。

  • 移除遗嘱配置后重试:暂时移除遗嘱相关的配置项,先尝试建立基础连接,确认连接正常后再重新配置遗嘱。如果移除遗嘱后连接成功,说明遗嘱的QoS设置与Broker的QoS限制存在冲突,可尝试使用更低的遗嘱QoS(如AtMostOnce)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:48:13