使用MQTTnet订阅Azure IoT Hub消息时,发布消息后连接断开
问题排查与解决方案
1. 修正凭证参数
你的代码中WithCredentials的密码参数错误,应传入设备的实际SAS令牌,而非字符串"SharedAccessSignature"。SAS令牌需通过设备主键生成,格式示例:
SharedAccessSignature sr={IoTHubName}.azure-devices.net%2Fdevices%2F{DeviceId}&sig={Signature}&se={ExpiryTime}
同时用户名格式应为{IoTHubName}.azure-devices.net/{DeviceId},无需附加/api-version=2018-06-30。修正后的凭证代码:
.WithCredentials("<IoTHub>.azure-devices.net/<Device-Id>", "SharedAccessSignature sr=...&sig=...&se=...")
2. 修正订阅主题
你当前订阅的devices/<Device-Id>/messages/events/是**设备上传到云(D2C)**的消息发布主题,设备端MQTT客户端无法通过该主题接收消息。根据场景选择正确主题:
- 若接收**云到设备(C2D)**消息,订阅主题应为:
devices/<Device-Id>/messages/devicebound/# - 若需接收所有设备的D2C消息,不能用设备端MQTT客户端订阅,需使用IoT Hub服务端方式(如Event Hub兼容端点、IoT Hub Service SDK),设备端无权限订阅D2C消息流。
3. 添加断开原因日志
在DisconnectedAsync事件中打印具体断开原因,帮助定位问题:
mqttClient.DisconnectedAsync += async (MqttClientDisconnectedEventArgs arg) => { Console.WriteLine($"Disconnected. Reason: {arg.Reason}"); if (arg.Exception != null) { Console.WriteLine($"Exception: {arg.Exception.Message}"); } };
4. 指定MQTT协议版本
Azure IoT Hub支持MQTT 3.1.1,显式指定协议版本避免兼容性问题:
var mqttClientOptions = new MqttClientOptionsBuilder() .WithClientId("<Device-Id>") .WithTcpServer("<IoTHub>.azure-devices.net", 8883) .WithCredentials("<IoTHub>.azure-devices.net/<Device-Id>", "你的SAS令牌") .WithTls(new MqttClientOptionsBuilderTlsParameters() { UseTls = true }) .WithCleanSession() .WithProtocolVersion(MqttProtocolVersion.V311) // 添加此行 .Build();
5. 确保SAS令牌权限正确
生成SAS令牌时,需包含deviceconnect权限,否则设备无法正常连接并订阅消息。
验证步骤
- 用正确的SAS令牌替换密码参数
- 切换到对应场景的订阅主题
- 运行代码后,通过Azure Portal或VS Code扩展发送C2D消息
- 查看控制台是否打印
Message received,而非断开连接提示
内容的提问来源于stack exchange,提问作者AMAR MATHUR
相关产品推荐
相关产品推荐

