客户端在尝试执行连接时已断开连接

Jor*_*ean 0 c# mqtt mosquitto .net-core

当尝试连接到本地运行的 Mosquitto MQTT 队列时,出现以下错误。

Unhandled exception. System.AggregateException: One or more errors occurred. (The client  has been disconnected while trying to perform the connection)
 ---> System.Net.Mqtt.MqttClientException: The client  has been disconnected while trying to perform the connection
   at System.Net.Mqtt.Sdk.MqttClientImpl.ConnectAsync(MqttClientCredentials credentials, MqttLastWill will, Boolean cleanSession)
Run Code Online (Sandbox Code Playgroud)

我在设置时使用默认选项System.Net.Mqtt.MqttClient

Unhandled exception. System.AggregateException: One or more errors occurred. (The client  has been disconnected while trying to perform the connection)
 ---> System.Net.Mqtt.MqttClientException: The client  has been disconnected while trying to perform the connection
   at System.Net.Mqtt.Sdk.MqttClientImpl.ConnectAsync(MqttClientCredentials credentials, MqttLastWill will, Boolean cleanSession)
Run Code Online (Sandbox Code Playgroud)

Mosquitto MQTT 日志中显示以下错误。

1644497589: New connection from 172.17.0.1:56792 on port 1883.

1644497589: New client connected from 172.17.0.1:56792 as camerasim (p2, c0, k0).

1644497589: Bad socket read/write on client camerasim: Invalid arguments provided.
Run Code Online (Sandbox Code Playgroud)

Bri*_*its 6

您看到的错误很可能是Mosquitto 2.0.12 中所做更改的结果:

修复了max_keepalive不适用于 MQTT v3.1.1 和 v3.1 连接的问题。现在,如果这些客户端的 keepalive 值超过 max_keepalive,则会被拒绝。此选项允许解决 CVE-2020-13849(适用于 MQTT v3.1.1 协议本身而不是实现)。

2.0.9 中的一项更改也开始发挥作用:

修复max_keepalive选项不适用于将 keepalive 设置为 0 的客户端连接。关闭 #2117。

这些更改是为了解决 MQTT 协议本身允许拒绝服务攻击的问题 ( CVE-2020-13849 )。

的默认值max_keepalive是,65535因此此更改意味着尝试将保持活动设置为 0(意味着没有保持活动)的连接将失败,除非mosquitto.conf指定max_keepalive 0。不幸的是,记录的错误 ( Bad socket read/write on client XXXXXYYYYY: Invalid arguments provided.) 并没有真正突出原因。

有两种可用的解决方案:

  • max_keepalive 0mosquitto.conf(Mosquitto 2.0.13 或更高版本)中指定。
  • 连接时指定 1 到 65535 之间的保持活动状态。xamarin/mqtt这意味着添加KeepAliveSecs到您的配置中;默认为 0

请注意,设置KeepAliveSecs = 1(根据您的答案)将允许您连接,但对于大多数用户来说可能有点短(KeepAliveSecs = 60可能更合适)。例如

var configuration = new MqttConfiguration {
    Port = 1883,
    KeepAliveSecs = 60,
    WaitTimeoutSecs = 2,
};
Run Code Online (Sandbox Code Playgroud)

我知道您已经找到了解决方案,但由于它可能会影响其他人,因此我认为值得解释一下问题的根本原因。许多 MQTT 库默认保持活动状态为 0,因此会受到影响(例如 Go Paho 记录了一个问题)。