Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
订阅Azure IoT集线器设备事件_Azure_Azure Iot Hub_Azure Eventhub - Fatal编程技术网

订阅Azure IoT集线器设备事件

订阅Azure IoT集线器设备事件,azure,azure-iot-hub,azure-eventhub,Azure,Azure Iot Hub,Azure Eventhub,我想阅读Azure IoT Hub中的“Microsoft.Devices.DeviceConnected”事件()。我发现的唯一例子涉及Azure事件网格,但我更愿意使用物联网中心的内部端点(事件中心)。这可能吗? 当我使用EventProcessorHost界面订阅内部事件中心时,我得到的只是D2C用户遥测消息。正如@PeterBons所说,Azure IoT Hub不支持此功能,但是可以在Azure IoT Hub之外使用Azure功能完成。以下屏幕片段显示了将EventGrid事件推送到

我想阅读Azure IoT Hub中的“Microsoft.Devices.DeviceConnected”事件()。我发现的唯一例子涉及Azure事件网格,但我更愿意使用物联网中心的内部端点(事件中心)。这可能吗?
当我使用EventProcessorHost界面订阅内部事件中心时,我得到的只是D2C用户遥测消息。

正如@PeterBons所说,Azure IoT Hub不支持此功能,但是可以在Azure IoT Hub之外使用Azure功能完成。以下屏幕片段显示了将EventGrid事件推送到IoT集线器流的集成:

如您所见,上述EventGridTrigger函数是Azure事件网格和Azure IoT中心之间的一个集成器。此集成商负责使用事件网格事件,映射到D2C消息,并将其作为具有Https协议的虚拟物联网设备(后端设备)发送到Azure物联网中心

更新:

以下代码段是Azure IoT集线器的Azure Function-Integrator示例:

#r "Microsoft.Azure.EventGrid"
#r "Newtonsoft.Json"

using System.Configuration;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Web;
using System.Net.Http;
using System.Text;
using System.Globalization;
using Newtonsoft.Json;
using Microsoft.Azure.EventGrid.Models;


// reusable client proxy
static HttpClientHelper iothub = new HttpClientHelper(Environment.GetEnvironmentVariable("AzureIoTHubShariedAccessPolicy"));

public static async Task Run(EventGridEvent eventGridEvent, ILogger log)
{
    log.LogInformation(eventGridEvent.Data.ToString());

    // my virtual backend iot device
    string deviceId = "Device13";
    var content = new StringContent(JsonConvert.SerializeObject(eventGridEvent), Encoding.UTF8, "application/json");

    await iothub.Client.PostAsync($"/devices/{deviceId}/messages/events?api-version=2018-06-30", content);
}




// helpers
class HttpClientHelper
{
    HttpClient client;
    DateTime expiringSaS;
    (string hostname, string keyname, string key) config;

    public HttpClientHelper(string connectionString)
    {
        config = GetPartsFromConnectionString(connectionString);
        client = new HttpClient() { BaseAddress = new Uri($"https://{config.hostname}")};
        SetAuthorizationHeader();         
    }

    public HttpClient Client
    {
        get
        {          
            if (expiringSaS < DateTime.UtcNow.AddMinutes(-1))
            {
               SetAuthorizationHeader();  
            }         
            return client;
        }
    }

    internal void SetAuthorizationHeader()
    {
        lock (client)
        {
            if (expiringSaS < DateTime.UtcNow.AddMinutes(-1)) 
            {
                string sasToken = GetSASToken(config.hostname, config.key, config.keyname, 1);
                if (client.DefaultRequestHeaders.Contains("Authorization"))
                    client.DefaultRequestHeaders.Remove("Authorization");
                client.DefaultRequestHeaders.Add("Authorization", sasToken);
                expiringSaS = DateTime.UtcNow.AddHours(1);
            }
        }
    }

    internal (string hostname, string keyname, string key) GetPartsFromConnectionString(string connectionString)
    {
        var parts = connectionString.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Split(new[] { '=' }, 2)).ToDictionary(x => x[0].Trim(), x => x[1].Trim());
        return (parts["HostName"] ?? "", parts["SharedAccessKeyName"] ?? "", parts["SharedAccessKey"] ?? "");
    }

    internal string GetSASToken(string resourceUri, string key, string keyName = null, uint hours = 24)
    {
        var expiry = GetExpiry(hours);
        string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
        HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(key));

        var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
        var sasToken = String.Format(CultureInfo.InvariantCulture, $"SharedAccessSignature sr={HttpUtility.UrlEncode(resourceUri)}&sig={HttpUtility.UrlEncode(signature)}&se={expiry}");
        if (!string.IsNullOrEmpty(keyName))
            sasToken += $"&skn={keyName}";
        return sasToken;
    }

    internal string GetExpiry(uint hours = 24)
    {
        TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
        return Convert.ToString((int)sinceEpoch.TotalSeconds + 3600 * hours);
    }
}

我只想补充一点,您可以非常轻松地在IoT Hub中的事件下创建事件订阅(使用事件网格),并将连接事件(例如设备连接或设备断开连接)推送到Azure功能、事件中心或服务总线等。

IoT Hub具有默认内置端点(消息/事件)这与事件中心兼容。通过将订阅中的其他服务链接到物联网中心,您可以创建自定义端点以将消息路由到


以下是相关的Azure文档

,除非您以某种方式从设备发送自定义事件,否则您不能这样做。好的,谢谢您。因此,为了澄清问题:我首先需要一个事件订阅来处理来自设备的事件。没有其他解决方案可以对这些事件采取行动,对吗?到目前为止,我管理的是使用全局事件网格资源(事件订阅)并将其连接到存储队列,这似乎也是一个不错的解决方案。如果你说“虚拟物联网设备”,它是否会以某种方式映射到那些已经在物联网中心注册的设备,或者它会创建第二个设备,或者它是如何工作的?首先,感兴趣的源(事件),例如设备连接/断开、设备注册/删除是Azure物联网中心,而不是设备。在上述解决方案中,该事件类型和主题的事件订阅连接到EventGridTrigger函数。“虚拟物联网设备”基本上是您的后端设备(在我的示例中,名称是Device13),必须事先手动或编程注册。在上面的示例中,设备13已经注册。如何将EventGrid事件映射到非遥测数据取决于您的要求。好的,这对我来说很有意义。但是,使用事件网格是一条可行之路,或者是否存在类似“消息路由”这样的替代方案,它似乎也提供了这种功能?如果您将您的方法与我的方法(我只是将全局创建的事件订阅连接到存储队列)进行比较,您会看到任何优点/缺点吗?也许在价格上有很大的不同。。。另外,您知道在使用全局事件订阅(事件网格)或创建新订阅方面的区别吗?这个场景可以只使用全局模式吗?您的事件模式是Push-Pull-Push,上面的解决方案是Push-Push,这是它们之间的主要区别。Azure IoT集线器中没有内置的消息路由用于此类源兴趣,例如连接的设备等。此事件类型的替代解决方案可用于功能诊断设置日志/度量,并流式传输到单独的事件中心感谢您的澄清!虚拟拥抱
{
  "bindings": [
    {
      "type": "eventGridTrigger",
      "name": "eventGridEvent",
      "direction": "in"
    }
  ],
  "disabled": false
}