Skip to main content

Azure IoT Edge Hub模块的消息路由

分类:  Azure物联网 标签:  #Azure #IoT Edge # 发布于: 2023-06-15 9:21:10

Azure IoT Edge两个系统模块Edge AgentEdge Hub, edge Agent主要是管理模块的安装和监控,Edge Hub用于模块或者子设备和IoT Hub之间的通讯。

我们可以把Edge Hub模块认为是缩小版的IoT Hub, 它拥有很多的IoT Hub的特性,在IoT Edge设备不在线的时候,它可以充当部分的IoT Hub的功能。 为了将模块或者子设备的消息路由到IoT HubEdge Hub提供了消息路由的功能。在用户使用部署的时候可以对消息路由进行定义,如果你不熟悉部署,请参考文章:<>

当我们使用Azure Portal添加部署的时候,无论是标准的自动部署,还是分层部署,都需要配置消息的路由,如下图:


从最后生成的部署清单中也可以看到edge hub的消息路由的基本语法是:

{
  "modulesContent": {
    "$edgeAgent": { ... },
    "$edgeHub": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "routes": {
          "route1": "FROM <source> WHERE <condition> INTO <sink>",
          "route2": {
            "route": "FROM <source> WHERE <condition> INTO <sink>",
            "priority": 0,
            "timeToLiveSecs": 86400
          }
        },
        "storeAndForwardConfiguration": {
          "timeToLiveSecs": 10
        }
      }
    },
    "module1": { ... },
    "module2": { ... }
  }
}

声明路由

路由声明是在模块Edge Hub的预期属性(desired property)的routes中声明,基本语法如下:

FROM {source|源} WHERE {condition|条件语句} INTO {sink|数据接收}

消息源的定义

对于路由的消息源可以采用如下的值:

  1. "/*": 所有从子设备或者模块的D2C消息,或者是twin更改的通知消息。
  2. "/twinChangeNotifications": 代表任何模块或者设备的twin更改事件或者(reported propertity)
  3. "/messages/*": 任何模块或者子设备的D2C消息
  4. "/messages/modules/*": 任何模块的消息(注意:这里没有子设备)
  5. "/messages/modules/
  6. "/messages/modules/
  7. "/messages/modules/

需要注意路由适用范围:子设备或者是模块。

消息选择的条件

在转发消息中,条件是可选的,如果不指定WHERE语句就表示所有的消息都会被路由,如果加上了WHERE,那么只有符合条件的语句才会被路由。

由于在IoT Edge和模块或者子设备之间传递的消息被格式化为json文档的格式,例如:

{ 
  "message": { 
    "systemProperties": { 
      "contentType": "application/json", 
      "contentEncoding": "UTF-8", 
      "iothub-message-source": "deviceMessages", 
      "iothub-enqueuedtime": "2017-05-08T18:55:31.8514657Z" 
    }, 
    "appProperties": { 
      "processingPath": "{cold | warm | hot}", 
      "verbose": "{true, false}", 
      "severity": 1-5, 
      "testDevice": "{true | false}" 
    }, 
    "body": "{\"Weather\":{\"Temperature\":50}}" 
  } 
}

上面的例子是IoT Hub定义的消息的通用格式。

WHERE条件语句是针对消息格式中的SystemPropertiesappPropertiesbody 中的属性。
那如何在条件语句中引用这三类属性呢?

  1. 引用SystemProperties$<propertyName> 或者 {$<propertyName>} 引用, 例如{$<contentType>}{$<iothub-message-source>}
  2. 引用appProperties<propertyName>, 直接使用名字,例如:processingPath, 或者 servertity
  3. 引用body: $body.<propertyName>, 例如$body.Weather

再举例,例如引用systemProperties:

FROM /messages/* WHERE NOT IS_DEFINED($contentType) INTO $upstream

消息接收(sink)

只有模块和IoT Hub可以接收消息,因此它的定义相对简单:

  1. $upstream: 代表消息会送到IoT Hub
  2. BrokeredEndpoint("/modules/<moduleId>/inputs/<input>): 定义消息被指定模块<moduleId>的指定<input>接收。

路由的其他属性

消息路由还有另外两个属性:

  • priority: 优先级, 值的范围是0-9, 0代表最高的优先级, 消息会优先处理。
  • timeToLiveSecs: 如果不设定该值,默认是从edge Hub的属性storeAndForwardConfiguration 配置继承。

定义格式

支持两种格式:

格式1:

"route1": "FROM <source> WHERE <condition> INTO <sink>",

格式2:

"route2": {
  "route": "FROM <source> WHERE <condition> INTO <sink>",
  "priority": 0,
  "timeToLiveSecs": 86400
}

消息路由介绍到这里,我们接下来介绍如何自定义edge agentedge hub的存储。