我已经设置了一个Azure Event Hub,我正在从Python脚本发送JSON格式的AMQP消息,并尝试使用Stream Analytics将这些消息流式传输到Power BI。 消息来自IoT设备的非常简单的设备活动
Python代码段是
msg = json.dumps({ "Hub": MAC, "DeviceID": id, "DeviceUID": ouid, "Signal": text, "Timestamp": dtz }, ensure_ascii=False, encoding='utf8')
message.body = msg
messenger.put(message)
messenger.send()
我在MS教程中使用示例C#消息阅读器从事件中心读取数据没有问题,输出为:
Message received. Partition: '2', Data: '??{"DeviceUID": "z_70b3d515200002e7_0", "Signal": "/on?1", "DeviceID": "1", "Hub": "91754623489", "Timestamp": "2016-07-15T07:56:50.277440Z"}'
但是当我尝试从事件中心测试Stream Analytics输入时,我收到错误
诊断:无法将输入事件反序列化为Json。一些可能的原因:1)格式错误的事件2)输入源配置了错误的序列化格式
我不确定格式错误的事件是什么意思 - 我假设Stream Analytics可以处理通过AMQP发送到事件中心的数据?
我无法看到C#应用程序收到的JSON有什么问题 - 除非BOM符号导致问题?
这是我对这一切的第一次尝试,我搜索过任何类似的帖子都无济于事,所以如果有人能指出我正确的方向,我真的很感激。
干杯 罗布
答案 0 :(得分:2)
这是由客户端API不兼容引起的。 Python使用Proton在AMQP Value消息的主体中发送JSON字符串。正文被编码为AMQP字符串(AMQP类型编码字节+字符串的utf8编码字节)。 Stream Analytics使用Service Bus .Net SDK,它将AMQP消息公开为EventData,其主体始终为字节数组。对于AMQP值消息,它包括AMQP类型编码字节,因为没有它们,不可能解码以下值。开头的这些额外字节将导致JSON序列化失败。
要实现消息体的互操作性,应用程序应确保发布者和消费者就其类型和编码达成一致。在这种情况下,发布者应该在AMQP数据消息中发送原始字节。使用Proton Python API,您可以尝试:
message.body = msg.encode('utf-8')
另一种解决方法是在应用程序属性中发送简单类型(例如字符串)。
其他人也遇到过这个问题。 https://github.com/Azure/amqpnetlite/issues/117
答案 1 :(得分:0)
正如@XinChen所说,问题是由AMQP协议引起的。
根据我的经验,下面的两种解决方法对于这种情况是有效的。
Send Event
REST API代替Azure Python SDK和AMQP,但其余api基于HTTP协议而不是高性能。答案 2 :(得分:0)
这两件事对我有用:
message.inferred = True
encoding='utf-8'
而不是encoding='utf8'
,如您的示例所示。更新了OP:
msg = json.dumps({ "Hub": MAC, "DeviceID": id, "DeviceUID": ouid, "Signal": text, "Timestamp": dtz }, ensure_ascii=False, encoding='utf-8')
message.body = msg
message.inferred = True
messenger.put(message)
messenger.send()
通过添加推断标志,我认为消息序列化器可以正确地推断出主体是字节并创建AMPQ DATA,从而解决@Xin Chen的问题。
消息的推断标志指示消息内容如何编码到AMQP节中。如果推断为真,则消息正文中的二进制和列表值将分别编码为AMQP DATA和AMQP SEQUENCE部分。如果推断为false,则消息正文中的所有值都将被编码为AMQP VALUE部分,而不管其类型如何。