非SDK方式向IoT Hub发送消息时如何定义应用属性?
问题原因与解决方法
这事儿的核心原因很简单:IoT Hub并不是通过解析Body里的JSON结构来区分应用属性和消息体的——SDK帮你做了「元数据属性」和「Payload(消息体)」的分离,但你自己构造的消息把所有内容都塞进了Payload里,所以IoT Hub自然会把整个JSON当成Body处理。
为什么SDK发送的消息能正常工作?
当你用Azure IoT C SDK发送消息时,SDK会自动把你设置的Application Properties放到消息的元数据字段里(对应HTTP的Header、MQTT的用户属性、AMQP的application-properties),而把实际的业务数据单独作为Payload发送。IoT Hub收到后,会分别识别这两部分内容,所以路由和Function里的EventData能正确获取属性。
不用SDK时,怎么让IoT Hub区分应用属性和消息体?
你需要把applicationProperties里的内容从Body中剥离出来,放到对应协议的元数据区域,Body只保留业务数据部分。下面分常用协议说明:
1. HTTP协议发送
- 应用属性要放在HTTP请求头里,前缀必须是
iothub-app-,比如:iothub-app-type: telemetryiothub-app-version: 1.0
- Body部分只保留原来的业务数据:
{ "device_id": "sensor1", "datetime": "2019-05-09T10:44:04Z", "channels": { "T": 24.42, "H": 44.87, "C": 1234 } } - 举个curl命令的示例:
curl -X POST \ https://{你的IoT Hub名称}.azure-devices.net/devices/{设备ID}/messages/events?api-version=2020-09-30 \ -H "Authorization: SharedAccessSignature sr={你的IoT Hub名称}.azure-devices.net&sig={签名}&se={过期时间}&skn=iothubowner" \ -H "Content-Type: application/json" \ -H "iothub-app-type: telemetry" \ -H "iothub-app-version: 1.0" \ -d '{ "device_id": "sensor1", "datetime": "2019-05-09T10:44:04Z", "channels": { "T": 24.42, "H": 44.87, "C": 1234 } }'
2. MQTT协议发送
- 把
type、version这类属性作为MQTT的**用户属性(User Properties)**添加到消息中,不要放到Payload里 - Payload只保留业务数据的JSON内容即可。大部分MQTT客户端(比如MQTTX、paho-mqtt)都支持设置用户属性
3. AMQP协议发送
- 将应用属性放到AMQP消息的
application-properties节点中,Payload单独设置为业务数据的JSON内容
总结
关键是要明确:IoT Hub的「应用属性」是消息的元数据,不是Payload的一部分。SDK帮你完成了元数据和Payload的拆分,自己构造消息时,必须手动把属性放到对应协议的元数据区域,而不是把所有内容都打包成一个JSON作为Body。
内容的提问来源于stack exchange,提问作者Thomas Mutzl
相关产品推荐
相关产品推荐

