Azure IoT Hub - 使用多个EventHubReceiver从不同设备接收事件

时间:2015-11-17 10:28:22

标签: azure iot azure-eventhub


我尝试使用" EventHubReceiver"从设备接收消息。 (Device2Cloud)。每个设备都应该拥有它自己的单接收器。

为所有设备创建一个单独的EventHubReceiver(每个分区)不是一个问题:

string iotHubconnectionString = CloudConfigurationManager.GetSetting("Microsoft.IotHub.ConnectionStringPayed");
string iotHubD2cEndpoint = "messages/events";
EventHubClient eventHubClient = EventHubClient.CreateFromConnectionString(iotHubconnectionString, iotHubD2cEndpoint);
EventHubRuntimeInformation runtimeInformation = eventHubClient.GetRuntimeInformation();

如果我想接收来自客户的消息,我会执行以下步骤:

EventHubReceiver eventHubReceiver = eventHubClient2.GetDefaultConsumerGroup().CreateReceiver(partition);  //Get the partitions via the runtimeInformation: string[] partitions = runtimeInformation.PartitionIds;
var incommingMessage = eventHubReceiver.ReceiveAsync();    //Wait here for incomming messages

它可以正常工作,但所有来自所有"设备"然后到达这个" EventHubReceiver"。我想有多个接收器,只接收来自单个设备的消息。
我试图更改以下代码行:

string iotHubD2cEndpoint = "messages/events";

string iotHubD2cEndpoint = "devices/{deviceID}/messages/events";

但这不能正常工作。我收到以下错误:

The link address 'devices/secondDevice/messages/events/$management' did not match any of the expected formats. Supported formats: '/$cbs', '/devices/{deviceid}/messages/events', '/devices/{deviceid}/messages/deviceBound', '/messages/deviceBound', '/messages/serviceBound/feedback', '/messages/events/*'.

所以问题是我得到了'devices/secondDevice/messages/events/$management'的{​​{1}} 我不知道,是否无法为每个设备创建一个EventHubReceiver,或者我在代码中出现错误或思考。

2 个答案:

答案 0 :(得分:2)

当设备向IoT Hub发送遥测数据时,事件可供云中的相关D2C端点使用,即事件中心兼容"。 它有一个"事件中心,如"行为,因此我们可以使用EventHubReceiver获取消息。 但是,事件中心在分区中工作,并且传入消息可以以循环方式分配给分区或散列分区键。 在IoT Hub架构中,我不知道它是否使用循环法,但它可能用于散列设备ID(作为分区键),因此来自设备的所有消息都进入分区。它并不意味着分区只包含该设备的消息!每个设备都有一个分区是不可能的:-) 所以...分区包含从不同设备混合的消息(但来自特定设备的消息总是在同一分区中)。 Event Hub接收器可以从分区读取,以便从更多设备获取所有消息。您需要根据设备ID区分它们。

答案 1 :(得分:0)

我忘了提及,我已经有了一个解决方案。但它不是很好:

  • 所有deviceThreads(每个分区和设备一个)等待(“WaitOne”)一点(使用AutoResetEvent锁定)
  • 我使用单个接收器接收所有消息
  • 我将消息放入每个设备的自己的队列中(包含设备对象(id和分区)作为键的字典和作为值的列表
  • 我使用“set”命令设置了一个空闲的线程集。
  • 线程在其队列中查找:
    • 如果队列中有消息,它会继续并返回带有“yield return”的结果 - >再次等待新消息
    • 否则它会设置不同的主题费用并返回冻结状态

所有线程循环一会儿(true)等待消息。 解决方案正在运行,但它看起来效率不高(有很多线程)并且有点复杂。