你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

了解和调用 IoT 中心的直接方法

IoT 中心直接方法使你能够从云中远程调用设备上的调用。 直接方法遵循请求-响应模式,适用于需要立即确认其结果的通信。 例如对设备的交互式控制,如打开风扇。 此功能用于即时操作过程不同的情况,即时操作的不同取决于设备能否响应。

注意

本文所述的功能只能用于 IoT 中心的标准层。 有关 IoT 中心基本层和标准/免费层的详细信息,请参阅选择适合你的解决方案的 IoT 中心层

每个设备方法针对一个设备。 如果你希望对多个设备调用直接方法,或者为已断开连接的设备计划方法调用,请参阅在多个设备上计划作业

只要拥有 IoT 中心的“服务连接”权限,任何人都可以调用设备上的方法。

如果你在使用所需属性、直接方法或云到设备消息方面有任何疑问,请参阅云到设备通信指导

方法生命周期

直接方法在设备上实现,可能需要在方法有效负载中进行 0 次或 0 次以上的输入才能正确地实例化。 可以通过面向服务的 URI ({iot hub}/twins/{device id}/methods/) 调用直接方法。 设备通过特定于设备的 MQTT 主题 ($iothub/methods/POST/{method name}/) 或通过 AMQP 链接(IoThub-methodnameIoThub-status 应用程序属性)接收直接方法。

备注

调用设备上的直接方法时,属性名称和值只能包含 US-ASCII 可打印字母数字,但下列组中的任一项除外:$ ( ) < > @ , ; : \ " / [ ] ? = { } SP HT

直接方法是同步的,在超时期限(默认值:30 秒;可设置值为 5 到 300 秒)过后,其结果不是成功就是失败。 直接方法适用于交互式场景,即当且仅当设备处于联机状态且可接收命令时,用户希望设备做出响应。 例如,打开手机的灯。 在此类方案中,用户需要立即看到结果是成功还是失败,以便云服务可以尽快根据结果进行操作。 设备可能会返回某些消息正文作为方法的结果,但这不是必需的。 无法保证基于方法调用的排序或者任何并发语义。

直接方法从云端只能通过 HTTPS 调用,从设备端可以通过 MQTT、AMQP、基于 WebSocket 的 MQTT 或 基于 WebSockets 的 AMQP 调用。

方法请求和响应的有效负载为最大 128 KB 的 JSON 文档。

从后端应用调用直接方法

若要从后端应用调用直接方法,请使用 Invoke 设备方法 REST API 或 IoT 中心服务 SDK 中的等效方法。

方法调用

设备上的直接方法调用是 HTTPS 调用,它由以下项构成:

  • 特定于设备的请求 URI 以及 API 版本:

    https://fully-qualified-iothubname.azure-devices.net/twins/{deviceId}/methods?api-version=2021-04-12
    
  • POST 方法

  • 标头,包含身份验证、内容类型和内容编码。

  • 透明的 JSON 正文 ,采用以下格式:

    {
        "connectTimeoutInSeconds": 200,
        "methodName": "reboot",
        "responseTimeoutInSeconds": 200,
        "payload": {
            "input1": "someInput",
            "input2": "anotherInput"
        }
    }
    

在请求中作为 responseTimeoutInSeconds 提供的值是 IoT 中心服务在设备上执行直接方法所需等待的时间。 将此超时设置为至少与设备的直接方法的预期执行时间一样长。 如果未提供超时,则使用默认值:30 秒。 responseTimeoutInSeconds 的最小值和最大值分别为 5 秒和 300 秒。

在请求中作为 connectTimeoutInSeconds 提供的值是在调用直接方法后,IoT 中心服务等待断开连接的服务进入联机状态所需的时间。 默认值为 0,表示在调用直接方法时,设备必须已处于联机状态。 connectTimeoutInSeconds 的最大值为 300 秒。

示例

此示例发起一个请求,以调用已注册到 Azure IoT 中心的 IoT 设备上的直接方法。

若要开始,请使用适用于 Azure CLI 的 Microsoft Azure IoT 扩展创建 SharedAccessSignature。

az iot hub generate-sas-token -n <iothubName> --du <duration>

接下来,将 Authorization 标头替换为新生成的 SharedAccessSignature,然后修改 iothubNamedeviceIdmethodNamepayload 参数,使之与下面的示例 curl 命令中的实现匹配。

curl -X POST \
  https://<iothubName>.azure-devices.net/twins/<deviceId>/methods?api-version=2021-04-12\
  -H 'Authorization: SharedAccessSignature sr=iothubname.azure-devices.net&sig=x&se=x&skn=iothubowner' \
  -H 'Content-Type: application/json' \
  -d '{
    "methodName": "reboot",
    "responseTimeoutInSeconds": 200,
    "payload": {
        "input1": "someInput",
        "input2": "anotherInput"
    }
}'

执行修改后的命令以调用指定的直接方法。 成功的请求将返回 HTTP 200 状态代码。

注意

上面的示例演示如何调用设备上的直接方法。 若要调用 IoT Edge 模块中的直接方法,请修改 URL 请求以包括 /modules/<moduleName>,如下所示:

https://<iothubName>.azure-devices.net/twins/<deviceId>/modules/<moduleName>/methods?api-version=2021-04-12

响应

后端应用接收响应,响应由以下项构成:

  • HTTP 状态代码:

    • 200 表示成功执行直接方法;
    • 404 表示设备 ID 无效,或者设备在调用直接方法后 connectTimeoutInSeconds 秒内未联机(请使用伴随的错误消息来了解根本原因);
    • 504 表示由于设备在 responseTimeoutInSeconds 秒内未响应直接方法调用而导致网关超时。
  • 标头,包含 请求 ID、内容类型和内容编码。

  • 采用以下格式的 JSON 正文:

    {
        "status" : 201,
        "payload" : {...}
    }
    

    statuspayload 均由设备提供,用于应对设备自身的状态代码和方法响应。

IoT Edge 模块的方法调用

调用模块上的直接方法受调用模块方法 REST API 或者 IoT 中心服务 SDK 中的等效方法支持。

使用 REST API 时,moduleId 将与请求 URI 中的 deviceId 一起传递;使用服务 SDK 时,作为参数传递。 例如 https://<iothubName>.azure-devices.net/twins/<deviceId>/modules/<moduleName>/methods?api-version=2021-04-12。 请求正文和响应类似于设备上调用的直接方法。

处理针对设备的直接方法

在 IoT 设备上,可以通过 MQTT、AMQP 或 WebSocket 上的任一协议接收直接方法。 IoT 中心设备 SDK 可帮助接收和响应设备上的直接方法,而无需担心基础协议详细信息。

MQTT

以下部分适用于 MQTT 协议。 若要详细了解如何将 MQTT 协议直接用于IoT 中心,请参阅 MQTT 协议支持

方法调用

设备通过 MQTT 主题接收直接方法请求:$iothub/methods/POST/{method name}/?$rid={request id}。 但是,request id 由 IoT 中心生成,并且无法提前知道,因此请订阅 $iothub/methods/POST/#,然后根据设备支持的方法名称筛选传递的消息。 (你将使用 request id 响应。)

设备接收的正文采用以下格式:

{
    "input1": "someInput",
    "input2": "anotherInput"
}

方法请求为 QoS 0。

响应

设备将响应发送到 $iothub/methods/res/{status}/?$rid={request id},其中:

  • status 属性是设备提供的方法执行状态。

  • $rid 属性是从 IoT 中心接收的方法调用中的请求 ID。 请求 ID 是一个十六进制格式的值。

正文由设备设置,可以是任何状态。

AMQP

以下部分适用于 AMQP 协议。 若要详细了解如何将 AMQP 协议直接用于 IoT 中心,请参阅 AMQP 协议支持

方法调用

设备通过在地址 amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound 上创建一个接收链接以接收直接方法请求。

AMQP 消息会到达表示方法请求的接收链接。 它包含以下部分:

  • 相关 ID 属性,其中包含一个应与相应的方法响应被传回的请求 ID。

  • 名为 IoThub-methodname 的一个应用程序属性,其中包含调用的方法名称。

  • AMQP 消息正文,其中包含作为 JSON 的方法有效负载。

响应

设备会创建一个发送链接以在 amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound 地址上返回方法响应。

方法的响应在发送链接上返回,并已按以下内容结构化:

  • 相关 ID 属性,其中包含在方法的请求消息中传递的请求 ID。

  • 名为 IoThub-status 的一个应用程序属性,其中包含用户提供的方法状态。

  • AMQP 消息正文,其中包含作为 JSON 的方法响应。

后续步骤

了解如何使用直接方法后,可根据兴趣参阅以下 IoT 中心开发人员指南文章: